diff --git a/README.md b/README.md index ee6a6c5..db87fc9 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,6 @@ Examples are available in exampleCPP. Status ------ -* The API is for EPICS Version 4 release 4.5.0 +* The API is for EPICS Version 4 release 4.6.0 diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 1efca70..8b3effc 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -2,7 +2,9 @@ EPICS V4 release 4.6 ==================== -The examples are moved to exampleCPP +* The examples are moved to exampleCPP +* Support for channelRPC is now available. +* removeRecord and traceRecord are now available. The test is now a regression test the can be ran via diff --git a/documentation/pvDatabaseCPP.html b/documentation/pvDatabaseCPP.html index 8debfff..89533f4 100644 --- a/documentation/pvDatabaseCPP.html +++ b/documentation/pvDatabaseCPP.html @@ -36,7 +36,7 @@

pvDatabaseCPP

-

Release 4.2-SNAPSHOT - 2016.06.02

+

Release 4.2-SNAPSHOT - 2016.07.14

Abstract

@@ -60,175 +60,109 @@ The minimum that an extension must provide is a top level PVStructure and a proc

Table of Contents

- -

-

Introduction

-

Overview

-

The main purpose of this project to make it easier to implement services that are accessed via pvAccess. +

Overview

+

+pvDatabaseCPP is one of the components of + +EPICS Version 4 + +

+

This document is only a guide to help locate code and documentation related to pvDatabaseCPP

-This project supplies a complete implementation of the server side of pvAccess, -which has the provider name local. +It is intended for developers that want to use pvDatabaseCPP.

-

-A service must provide a top level PVStructure and a process method. -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. +

Developer Guide

+

A guide for developers is available at + +developerGuide + +

+

This guide discusses all the components that are part of an EPICS V4 release. +Some understanding of the components and how they are related is necessary in order to +develop code that uses pvDatabaseCPP. +In particular read everything related to pvDatabase. +

+

The developerGuide discusses code in a way that applies to both CPP and C++. +For the descriptions of the CPP specific code consult the next section.

-

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. -Each record has a name which is the channelName for pvAccess. -A local Channel Provider implements the complete ChannelProvider and -Channel interfaces as defined by pvAccess. -The local provider provides access to the records in the pvDatabase. -This local provider is accessed by the remote pvAccess server. -A record is smart because code can be attached to a record, which is accessed via a method named process.

+

doxygen

+

doxygen documentation is available at +doxgen +

-

This document describes components that provide the following features:

+

pvDatabaseCPP

+

pvDatabaseCPP itself has the following implementations of a PVRecord

-
database
-
This encapsulates the concept of a database of memory resident smart records. - The two main components are: -
-
pvRecord
-
This encapsulates the concept of a smart record. It can be processed. - Changes to field values can be trapped. A record can be locked.
-
pvDatabase
-
This is a database of pvRecords. - Records can be added and removed from a database.
-
-
-
pvAccess
-
This is a complete implementation of ChannelProvider and Channel - as defined by pvAccess. - It is used by the server side of pvAccess to attach to pvRecords. -
-
Main and V3IOC
-
The pvDatabase can be provided via a Main program or can be part - of a V3IOC. In the later case the IOC has both a database of V3 Records - and a pvDatabase.
+
RemoveRecord.cpp
+
+ This is the code that is used to delete another record in the same IOC. +
+
TraceRecord.cpp
+
+ This is the code that is used to set the trace level + in another record in the same IOC. +
-

Base classes make it easy to create record instances. -The code attached to each record must create the top -level PVStructure and the following three methods:

-
-
init
-
This is a method for initializing the support. - It returns true if successful and false otherwise. -
-
process
-
This is what makes a record smart. -
-
destroy
-
This releases and resources used by the implementation.
-
-

Doxygen documentation is available at doxygenDoc

-

Getting started

-

The first step is to build pvDatabaseCPP as described in the next section.

-

A separate project exampleCPP has examples for pvDatabaseCPP -and for pvaClientCPP. -See it for examples. +

exampleCPP

+

Example code is available as part of this release. + +exampleCPP + +

+

In particular look at the example code mentioned in the following sub-sections.

-

Features Required for localChannelProvider

-
-
copy and monitor
-
pvDataCPP provides facilities copy and monitor. - This facilities allow a client to access an arbitrary subset - of the fields in the top level structure associated with a channel, - and to monitor changes in the top level structure. - pvDatabaseCPP uses what pvDataCPP provides and has code that - associates these facilities with a PVRecord. -
-
PVRecord and PVDatabase
-
Defined below.
-
The localChannelProvider itself
+

database

+

This has many examples of how to create both soft records and records that implement +other functionality.

+
+
exampleDatabase.cpp
- The localChannelProvider accesses data from PVRecords. - It implements all channel methods except channelRPC, - which is implemented by pvAccessCPP. + This shows how to create soft records of each pvData type.
+ In addition shows how to create instances of the following two records. +
+
exampleHelloRecord.cpp
+
+ This is a simple "hello world" that is intentended to be used via a channelPutGet request. +
+
exampleHelloRPC.cpp
+
+ This is a simple "hello world" that is intentended to be used via a channelRPC request. +
+
exampleDatabaseMain.cpp
+
+ This shows how to create a standalone IOC. +
+
ioc and iocBoot
+
+ This has code and examples to create a V3 IOC which also has a PVDatabase.
-

Features Required for pvRecord

-
-
PVDatabase
-
This holds a set of PVRecords. - It has methods to find, add, and remove records.
-
PVRecord
-
This, and a set of related interfaces, provides the following: -
-
Access to top level PVStructure
-
PVRecord is a wrapper on a top level pvStructure.
-
Record locking
-
A record can be locked and unlocked. - A record must be locked whenever data in the pvStructure is accessed. -
-
Trapping data changes
-
A client can request to be notified when data in the pvStructure - is modified. - It can do this on a field by field basis.
-
A method named process
-
-

The process method is called when a pvAccess client requests that a record be processed. - If a top level timeStamp field exists, - the default process method just sets the timeStamp to the currect time. - A service is created by implementing process and providing a top level PVStructure. -

-
-
+

exampleLink

+

This shows how to implement a record that has a link to another record

+
+
exampleMonitorLinkRecord
+
+ This creates a monitor link to another record. +
+
exampleGetLinkRecord
+
+ This creates a get link to another record. +
+
examplePutLinkRecord
+
+ This creates a put link to another record.
-

Building pvDatabaseCPP

-

-If a proper RELEASE.local is present one directory level above pvDatabaseCPP. -

-

-Just type: -

-
-make
-
-

-An example of a proper RELEASE.local is: -

-
-EPICS4_DIR=/home/epicsv4/master
-EXAMPLE=${EPICS4_DIR}/exampleCPP
-PVDATABASE=${EPICS4_DIR}/pvDatabaseCPP
-PVACLIENT=${EPICS4_DIR}/pvaClientCPP
-PVASRV=${EPICS4_DIR}/pvaSrv
-PVACCESS=${EPICS4_DIR}/pvAccessCPP
-NORMATIVETYPES=${EPICS4_DIR}/normativeTypesCPP
-PVDATA=${EPICS4_DIR}/pvDataCPP
-PVCOMMON=${EPICS4_DIR}/pvCommonCPP
-
-EPICS_BASE=/home/install/epics/base
-
- -

pvDatabaseCPP can also be built if a file RELEASE.local exists in directory configure. -To create one do the following:

-
-mrk> pwd
-/home/hg/pvDatabaseCPP/configure
-mrk> cp ExampleRELEASE.local RELEASE.local
-
-

Then edit RELEASE.local so that it has the correct location of each -product pvDatabaseCPP requires. -Than at the top level just execute make:

-
-mrk> cd ..
-mrk> pwd
-/home/epicsv4/master/pvDatabaseCPP
-mrk> make
-

iocshell commands

Shell commands are made available via the standard DBD include mechanism provided by iocCore. @@ -252,694 +186,6 @@ pvDatabaseCPP

In addition any code that implements a PVRecord must implement an ioc command. Look at any of the examples in exampleCPP to see how to implement shell commands.

-

database

-

src/database

-

This Directory has the following files:

-
-
pvDatabase.h
-
- This is what is described in this section. -
-
pvDatabase.cpp
-
- The implementation of PVDatabase. -
-
pvRecord.cpp
-
- The implementation of the base class for PVRecord. - It can also implement record instances with a process - method does nothing. - This can be used to create a "dumb" record where all changes are - done by clients. -
-
-

src/special

-

This directory has the following files:

-
-
traceRecord.h
-
This implements a PVRecord that can set the trace level for - another record. See below for a discussion of trace level.
- -
-

pvDatabase.h

-

The classes in pvDatabase.h describe a database of memory resident -smart records. -It describes the following classes:

-
-
PVRecord
-
This provides the methods required by localChannelProvider to implement Channel.
-
PVRecordField
-
PVRecordStructure
-
These wrap PVField and PVStructure so that pvCopy and monitor - can be implemented.
-
PVRecordClient
-
This is called by anything that accesses PVRecord.
-
PVListener
-
This is implemented by anything that wants to trap calls to PVRecord::message.
-
PVDatabase
-
This is a database of PVRecords.
-
-

Each class is described in a separate subsection.

-

C++ namespace and typedefs

-
-namespace epics { namespace pvDatabase {
-
-class PVRecord;
-typedef std::tr1::shared_ptr<PVRecord> PVRecordPtr;
-typedef std::map<epics::pvData::String,PVRecordPtr> PVRecordMap;
-
-class PVRecordField;
-typedef std::tr1::shared_ptr<PVRecordField> PVRecordFieldPtr;
-typedef std::vector<PVRecordFieldPtr> PVRecordFieldPtrArray;
-typedef std::tr1::shared_ptr<PVRecordFieldPtrArray> PVRecordFieldPtrArrayPtr;
-
-class PVRecordStructure;
-typedef std::tr1::shared_ptr<PVRecordStructure> PVRecordStructurePtr;
-
-class PVRecordClient;
-typedef std::tr1::shared_ptr<PVRecordClient> PVRecordClientPtr;
-
-class PVListener;
-typedef std::tr1::shared_ptr<PVListener> PVListenerPtr;
-
-class PVDatabase;
-typedef std::tr1::shared_ptr<PVDatabase> PVDatabasePtr;
-
- -

class PVRecord

-

NOTES:

-
    -
  • This section uses the name record instead of "an instance of PVRecord".
  • -
  • Most clients will access a record via the local channel provider, - i. e. via pvAccess. - Thus this section is mainly of interest to - the local channel provider and record implementers.
  • -
  • Most readers will not care about most of the PVRecord methods. - Most of the methods are used by the pvAccess code. - Service implementers will mostly be interested in methods init and process. - These are described first. -
  • -
-

PVRecord Methods

-
-class PVRecord
-     public std::tr1::enable_shared_from_this<PVRecord>
-{
-public:
-    POINTER_DEFINITIONS(PVRecord);
-
-    virtual bool init() ;
-    virtual void start() {}
-    virtual void process() {}
-    virtual void destroy();
-
-    static PVRecordPtr create(
-        std::string const & recordName,
-        epics::pvData::PVStructurePtr const & pvStructure);
-    virtual ~PVRecord();
-    std::string getRecordName();
-    PVRecordStructurePtr getPVRecordStructure();
-    PVRecordFieldPtr findPVRecordField(
-        epics::pvData::PVFieldPtr const & pvField);
-    void lock();
-    void unlock();
-    bool tryLock();
-    void lockOtherRecord(PVRecordPtr const & otherRecord);
-    bool addPVRecordClient(PVRecordClientPtr const & pvRecordClient);
-    bool removePVRecordClient(PVRecordClientPtr const & pvRecordClient);
-    void detachClients();
-    bool addListener(PVListenerPtr const & pvListener);
-    bool removeListener(PVListenerPtr const & pvListener);
-    ServicePtr getService(PVStructurePtr const & pvRequest)
-    void beginGroupPut();
-    void endGroupPut();
-    int getTraceLevel();
-    void setTraceLevel(int level);
-protected:
-    PVRecord(
-        std::string const & recordName,
-        epics::pvData::PVStructurePtr const & pvStructure);
-    void initPVRecord();
-    epics::pvData::PVStructurePtr getPVStructure();
-    PVRecordPtr getPtrSelf()
-    {
-        return shared_from_this();
-    }
-private:
-...
-}
-
-

The methods are:

-
-
init
-
Virtual method. - Derived classes must implement this method. - This method Must call initPVRecord. -
-
start
-
Virtual method. - Optional method for derived class. - It is called before record is added to database. - The base method does nothing. -
-
process
-
Virtual method. - Derived classes usually implement this method. - It implements the semantics for the record. -
- If a top level timeStamp exists the base class set it equal - to the current time. -
-
destroy
-
- Destroy the PVRecord and any context. -
- Release any resources used and get rid of listeners and requesters. - If derived class overrides this then it must call this base class destroy() - after it has destroyed any resorces it uses. -
- It can be called for several reasons. - Some examples are: -
    -
  • By pvDatabase when it is destroyed.
  • -
  • By other code that wants to destroy the record
  • -
-
-
create
-
Static method to create a soft record. - A soft record implements process by setting an optional top level timeStamp - to the current time. -
- A derived class should have it's own static create method. -
-
~PVRecord
-
- This calls destroy. -
-
getRecordName
-
Return the recordName.
-
getPVRecordStructure
-
Get the top level PVStructure.
-
findPVRecordField
-
Given a PVFieldPtr return the PVRecordFieldPtr for the field.
-
lock and unlock
-
Lock and Unlock the record. - Any code accessing the data in the record or calling other PVRecord methods - must have the record locked.
-
tryLock
-
If true then just like lock. - If false client can not access record. - A client can try to simultaneously hold the lock for more than two records - by calling this method. But must be willing to accept failure. -
-
lockOtherRecord
-
A client that holds the lock for one record can lock one other record. - A client must not call this if the client already has the lock for - more then one record. -
-
addPVRecordClient
-
- Every client that accesses the record must call this so that - the client can be notified when the record is deleted. -
-
removePVRecordClient
-
- Client is no longer accessing the record. -
-
detachClients
-
- Ask all clients to detach from the record -
-
addListener
-
- Add a PVListener. - This must be called before calling pvRecordField.addListener. -
-
removeListener
-
- Removes a listener. - The listener will also be removed from all fields to which it is attached. -
-
getService
-
- Virtual method. - A derived class implements this method if it supports channelRPC. - It implements the semantics for the channelRPC. - The base class returns null. -
-
beginGroupPut
-
Begin a group of puts. - This results in all registered PVListeners being called
-
endGroupPut
-
End a group of puts. - This results in all registered PVListeners being called.
-
getTraceLevel
-
This can be used for debugging. There are currently three - levels that are used by existing code. -
-
0
-
Produce no trace messages.
-
1
-
Issue a message to std::cout whenever anything is created - or destroyed.
-
2
-
In addition to lifetime messages also issue a message - whenever the record is accessed by pvAccess client.
-
-
-
setTraceLevel
-
Set the trace level. Note that special, described below. - provides a record support that allows a pvAccess client - to set the trace level of a record.
-
-

The protected methods are:

-
-
PVRecord
-
The constructor. It requires a recordName and a top level PVStructure.
-
initPVRecord
-
This method must be called by derived class.
-
getPVStructure
-
Called by derived class.
-
-

class PVRecordField

-
-class PVRecordField {
-     public virtual epics::pvData::PostHandler,
-     public std::tr1::enable_shared_from_this<PVRecordField>
-public:
-    POINTER_DEFINITIONS(PVRecordField);
-    PVRecordField(
-        epics::pvData::PVFieldPtr const & pvField,
-        PVRecordStructurePtr const & parent,
-        PVRecordPtr const & pvRecord);
-    virtual ~PVRecordField();
-    virtual void destroy();
-    PVRecordStructurePtr getParent();
-    epics::pvData::PVFieldPtr getPVField();
-    std::string getFullFieldName();
-    std::string getFullName();
-    PVRecordPtr getPVRecord();
-    bool addListener(PVListenerPtr const & pvListener);
-    virtual void removeListener(PVListenerPtr const & pvListener);
-    virtual void postPut();
-protected:
-    PVRecordFieldPtr getPtrSelf()
-    {
-        return shared_from_this();
-    }
-    virtual void init();
-    virtual void postParent(PVRecordFieldPtr const & subField);
-    virtual void postSubField();
-private:
-...
-};
-
-

When PVRecord is created it creates a PVRecordField for every field in the PVStructure -that holds the data. It has the following methods: -

- -
-
PVRecordField
-
The constructor.
-
~PVRecordField
-
The destructor.
-
destroy
-
Called by PVRecordStructure when it's destroy method is called.
-
getParent
-
Get the parent PVRecordStructure for this field.
-
getPVField
-
Get the PVField associated with this PVRecordField.
-
getFullFieldName
-
This gets the full name of the field, i.e. field,field,..
-
getFullName
-
This gets recordName plus the full name of the field, i.e. recordName.field,field,..
-
getPVRecord
-
Returns the PVRecord to which this field belongs.
-
addListener
-
Add A PVListener to this field. - Whenever this field or any subfield if this field is modified the listener will be notified. - PVListener is described below. - Before a listener can call addListener it must first call PVRecord.registerListener.
-
removeListener
-
Remove a PVListener.
-
postPut
-
This is called by the code that implements the data interface. - It is called whenever the put method is called.
-
-

class PVRecordStructure

-
-class PVRecordStructure : public PVRecordField {
-public:
-    POINTER_DEFINITIONS(PVRecordStructure);
-    PVRecordStructure(
-        epics::pvData::PVStructurePtr const & pvStructure,
-        PVRecordStructurePtr const & parent,
-        PVRecordPtr const & pvRecord);
-    virtual ~PVRecordStructure();
-    virtual void destroy();
-    PVRecordFieldPtrArrayPtr getPVRecordFields();
-    epics::pvData::PVStructurePtr getPVStructure();
-    virtual void removeListener(PVListenerPtr const & pvListener);
-    virtual void postPut();
-protected:
-    virtual void init();
-private:
-...
-};
-
-

When PVRecord is created it creates a PVRecordStructure for every structure field in the PVStructure -that holds the data. It has the following methods: -

-
-
PVRecordStructure
-
The constructor.
-
~PVRecordStructure
-
The destructor.
-
getPVRecordFields
-
Get the PVRecordField array for the subfields
-
getPVStructure
-
Get the PVStructure for this field.
-
removeListener
-
Remove a PVListener.
-
postPut
-
This is called by the code that implements the data interface. - It is called whenever the put method is called.
-
-

class PVRecordClient

-
-class PVRecordClient {
-    POINTER_DEFINITIONS(PVRecordClient);
-    virtual ~PVRecordClient();
-    virtual void detach(PVRecordPtr const & pvRecord);
-};
-
-

where

-
-
~PVRecordClient
-
The destructor.
-
detach
-
The record is being removed from the master database,
-
-

class PVListener

-
-class PVListener {
-    virtual public PVRecordClient
-public:
-    POINTER_DEFINITIONS(PVListener);
-    virtual ~PVListener();
-    virtual void dataPut(PVRecordFieldPtr const & pvRecordField) = 0;
-    virtual void dataPut(
-        PVRecordStructurePtr const & requested,
-        PVRecordFieldPtr const & pvRecordField) = 0;
-    virtual void beginGroupPut(PVRecordPtr const & pvRecord) = 0;
-    virtual void endGroupPut(PVRecordPtr const & pvRecord) = 0;
-    virtual void unlisten(PVRecordPtr const & pvRecord);
-};
-
-

where

-
-
~PVListener
-
The destructor.
-
dataPut(PVRecordFieldPtr const & pvRecordField)
-
pvField has been modified. - This is called if the listener has called PVRecordField::addListener for pvRecordField.
-
dataPut( - PVRecordStructurePtr const & - requested,PVRecordFieldPtr const & pvRecordField)
-
pvField has been modified. - Requested is the field to which the requester issued a pvField->addListener. - This is called if the listener has called PVRecordField->addListener for requested.
-
beginGroupPut
-
A related set of changes is being started.
-
endGroupPut
-
A related set of changes is done.
-
unlisten
-
The record is being destroyed. The listener must release all - access to the record.
-
-

class PVDatabase

-
-class PVDatabase : virtual public epics::pvData::Requester {
-public:
-    POINTER_DEFINITIONS(PVDatabase);
-    static PVDatabasePtr getMaster();
-    virtual ~PVDatabase();
-    virtual void destroy();
-    PVRecordPtr findRecord(std::string const & recordName);
-    bool addRecord(PVRecordPtr const & record);
-    epics::pvData::PVStringArrayPtr getRecordNames();
-    bool removeRecord(PVRecordPtr const & record);
-private:
-    PVDatabase();
-};
-
-

where

-
-
getMaster
-
Get the master database. This is the database that localChannelProvider access.
-
~PVDatabase
-
- The destructor. -
-
destroy
-
- This is called by remote channelAccess when process exits. - This destroys and removes all records in the PVDatabase. -
-
findRecord
-
Find a record. An empty pointer is returned if the record is not in the database.
-
addRecord
-
Add a record to the database. - If the record already exists it is not modified and false is returned.
-
getRecordNames
-
Returns an array of all the record names.
-
removeRecord
-
Remove a record from the database. - If the record was not in the database false is returned.
-
-

pvAccess

-

This is code that provides an implementation of channelProvider as -defined by pvAccess. -It provides access to PVRecords and is accessed by the server side of remote pvAccess. -It uses the copy and monitor facilities from pvDataCPP and connects -them to a PVRecord. -

-

The implementation is a complete implementation of channelProvider -and channel.

-

The following provides a brief description of each channel method that -is implemented.

-

channelProcessLocal

-

Implements channelProcess.

-

channelGetLocal

-

Implements channelGet.

-

channelPutLocal

-

Implements channelPut.

-

channelPutGetLocal

-

Implements channelPutGet.

-

channelArrayLocal

-

Implements channelArray.

-

ChannelRPCLocal

-

Implements channelRPC.

-

MonitorLocal

-

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 (implemented 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. -

-

The following two sections provide a few more details about MonitorLocal -and PVCopyMonitor.

-

MonitorLocal

-

MonitorLocal implements the following abstract base classes:

-
-
Monitor
-
This is described by pvDataCPP. - It has methods start, stop, poll, and release. - These methods are called by the pvAccess client -
-
PVCopyMonitorRequester
-
This has methods releaseActiveElement and unlisten. - These methods are called by PVCopyMonitor. -
-
-MonitorLocal manages the following: -
-
MonitorElementQueue
-
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. -
-
activeElement
-
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. -
-
-

A brief description on each method in MonitorLocal is:

-
-
start
-
- 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) -
-
stop
-
- Called by client. - With no lock held calls pvCopyMonitor->stopMonitoring(activeElement) -
-
poll
-
- Called by client. - With a lock held it calls queue->getUsed(); -
-
release
-
- Called by client. - With a lock held it calls queue->releaseUsed(); -
-
releaseActiveElement
-
- 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, -
-
unlisten
-
- With no lock held it calls monitorRequester->unlisten(getPtrSelf()); -
-
-

PVCopyMonitor

-

-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. -

-

A brief description of the pvCopyMonitor methods is:

-
-
startMonitoring
-
With no lock held it sets its monitorElement to the - startElement passed 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. -
-
stopMonitoring
-
- With no lock held it calls pvRecord->removeListener(getPtrSelf()); -
-
dataPut
-
- 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. -
-
beginGroupPut
-
- With a lock held it - sets isGroupPut true and dataChanged false. -
-
endGroupPut
-
- With a lock held it sets isGroupPut false. - With no lock held and dataChanged true it calls - pvCopyMonitorRequester->releaseActiveElement() -
-
unlisten
-
- Just calls pvCopyMonitorRequester->unlisten(); -
-
- -

special

-

This section provides traceRecord which implements a PVRecord that allows a client to set -the trace level of another PVRecord. It follows the pattern of a channelPutGet -record:

-
-traceRecord
-    structure argument
-        string recordName 
-        int level 0
-    structure result
-        string status 
-
-where: -
-
recordName
-
The name of the record to set the trace level.
-
level
-
The level to set. The meaning is: -
-
0
-
No trace messages generated
-
1
-
Lifecycle messages will be generated. - This all channel create and destroy instances will be shown.
-
2
-
In addition to lifecycle messages a message will be generated - for each get and put request.
-
>2
-
Currently no definition
-
-
-
result
-
The result of a cannelPutGet request
-
-

testExampleServerMain.cpp has an example of how to create a traceRecord:

-
-PVDatabasePtr master = PVDatabase::getMaster();
-PVRecordPtr pvRecord;
-String recordName;
-bool result(false);
-recordName = "traceRecordPGRPC";
-pvRecord = TraceRecord::create(recordName);
-result = master->addRecord(pvRecord);
-if(!result) cout<< "record " << recordName << " not added" << endl;
-
- -
diff --git a/src/pv/channelProviderLocal.h b/src/pv/channelProviderLocal.h index aee9e41..5405006 100644 --- a/src/pv/channelProviderLocal.h +++ b/src/pv/channelProviderLocal.h @@ -67,15 +67,16 @@ class epicsShareClass MonitorFactory public: POINTER_DEFINITIONS(MonitorFactory); /** - * Destructor + * @brief Destructor */ virtual ~MonitorFactory(); /** - * Destroy the monitor factory. + * @brief Destroy the monitor factory. */ virtual void destroy(); /** - * Create a monitor on a record. + * @brief 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. @@ -113,21 +114,22 @@ class epicsShareClass ChannelProviderLocal : public: POINTER_DEFINITIONS(ChannelProviderLocal); /** - * Destructor + * @brief Destructor */ virtual ~ChannelProviderLocal(); /** - * Destroy the channel provider. + * @brief Destroy the channel provider. + * * Probably never called. */ virtual void destroy(); /** - * Returns the channel provider name. + * @brief Returns the channel provider name. * @return local */ virtual std::string getProviderName(); /** - * Returns either a null channelFind or a channelFind for records in the PVDatabase. + * @brief 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. @@ -142,8 +144,9 @@ public: 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. + * @brief Calls method channelListRequester::channelListResult. + * + * This 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. @@ -152,7 +155,8 @@ public: virtual epics::pvAccess::ChannelFind::shared_pointer channelList( epics::pvAccess::ChannelListRequester::shared_pointer const & channelListRequester); /** - * Create a channel for a record. + * @brief 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. @@ -164,7 +168,7 @@ public: epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority); /** - * Create a channel for a record. + * @brief 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. @@ -219,11 +223,12 @@ public: PVRecordPtr const & pvRecord ); /** - * Destructor + * @brief Destructor */ virtual ~ChannelLocal(); /** - * Destroy the channel. + * @brief 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. @@ -231,18 +236,20 @@ public: */ virtual void destroy(); /** + * @brief Detach from the record. + * * This is called when a record is being removed from the database. * Calls destroy. * @param pvRecord The record being destroyed. */ virtual void detach(PVRecordPtr const &pvRecord); /** - * Get the requester name. + * @brief Get the requester name. * @return returns the name of the channel requester. */ virtual std::string getRequesterName(); /** - * Passes the message to the channel requester. + * @brief Passes the message to the channel requester. * @param message The message. * @param messageType The message type. */ @@ -250,7 +257,7 @@ public: std::string const & message, epics::pvData::MessageType messageType); /** - * Get the channel provider + * @brief Get the channel provider * @return The provider. */ virtual epics::pvAccess::ChannelProvider::shared_pointer getProvider() @@ -258,7 +265,7 @@ public: return provider; } /** - * Get the remote address + * @brief Get the remote address * @return local */ virtual std::string getRemoteAddress(); @@ -268,22 +275,23 @@ public: */ virtual epics::pvAccess::Channel::ConnectionState getConnectionState(); /** - * Get the channel name. + * @brief Get the channel name. * @return the record name. */ virtual std::string getChannelName(); /** - * Get the channel requester + * @brief Get the channel requester * @return The channel requester. */ virtual epics::pvAccess::ChannelRequester::shared_pointer getChannelRequester(); /** - * Is the channel connected? - * @return true + * @brief Is the channel connected? + * @return true. */ virtual bool isConnected(); /** - * Get the introspection interface for subField. + * @brief Get the introspection interface for subField. + * * The introspection interface is given via GetFieldRequester::getDone. * @param requester The client callback. * @param subField The subField of the record. @@ -301,8 +309,8 @@ public: virtual epics::pvAccess::AccessRights getAccessRights( epics::pvData::PVField::shared_pointer const &pvField); /** - * Create a channelProcess. - * See pvAccess.html for details. + * @brief Create a channelProcess. + * * @param requester The client callback. * @param pvRequest The options specified by the client. * @return A shared pointer to the newly created implementation. @@ -312,8 +320,8 @@ public: epics::pvAccess::ChannelProcessRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest); /** - * Create a channelGet. - * See pvAccess.html for details. + * @brief Create a channelGet. + * * @param requester The client callback. * @param pvRequest The options specified by the client. * @return A shared pointer to the newly created implementation. @@ -323,8 +331,8 @@ public: epics::pvAccess::ChannelGetRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest); /** - * Create a channelPut. - * See pvAccess.html for details. + * @brief Create a channelPut. + * * @param requester The client callback. * @param pvRequest The options specified by the client. * @return A shared pointer to the newly created implementation. @@ -334,8 +342,8 @@ public: epics::pvAccess::ChannelPutRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest); /** - * Create a channelPutGet. - * See pvAccess.html for details. + * @brief Create a channelPutGet. + * * @param requester The client callback. * @param pvRequest The options specified by the client. * @return A shared pointer to the newly created implementation. @@ -345,10 +353,9 @@ public: 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. + * @brief Create a channelRPC. + * + * The PVRecord must implement getService or an empty shared pointer is returned. * @param requester The client callback * @param pvRequest The options specified by the client. * @return null. @@ -357,8 +364,8 @@ public: epics::pvAccess::ChannelRPCRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest); /** - * Create a monitor. - * See pvAccess.html for details. + * @brief Create a monitor. + * * @param requester The client callback. * @param pvRequest The options specified by the client. * @return A shared pointer to the newly created implementation. @@ -368,8 +375,8 @@ public: epics::pvData::MonitorRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest); /** - * Create a channelArray. - * See pvAccess.html for details. + * @brief Create a channelArray. + * * @param requester The client callback. * @param pvRequest The options specified by the client. * @return A shared pointer to the newly created implementation. @@ -379,12 +386,12 @@ public: epics::pvAccess::ChannelArrayRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest); /** - * calls printInfo(std::cout); + * @brief calls printInfo(std::cout); */ virtual void printInfo(); /** - * displays a message - * "ChannelLocal provides access to a record in the local PVDatabase". + * @brief displays a message + * * @param out the stream on which the message is displayed. */ virtual void printInfo(std::ostream& out); diff --git a/src/pv/pvDatabase.h b/src/pv/pvDatabase.h index 62b6a0a..71bb0d9 100644 --- a/src/pv/pvDatabase.h +++ b/src/pv/pvDatabase.h @@ -1,13 +1,8 @@ -/* pvDatabase.h */ /** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS pvData is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ -/** - * @author mrk - * @date 2012.11.20 - */ #ifndef PVDATABASE_H #define PVDATABASE_H @@ -60,9 +55,13 @@ class PVDatabase; typedef std::tr1::shared_ptr PVDatabasePtr; /** - * @brief Base interface for a record. + * @brief Base interface for a PVRecord. * + * It is also a complete implementation for soft records. + * A soft record is a record where method process sets an + * optional top level timeStamp field to the current time and does nothing else. * @author mrk + * @date 2012.11.20 */ class epicsShareClass PVRecord : public epics::pvData::PVCopyTraverseMasterCallback, @@ -75,19 +74,21 @@ public: */ virtual ~PVRecord(); /** - * Virtual initialization method. - * Must be implemented by derived classes. - * This method Must call initPVRecord. + * @brief Optional initialization method. + * + * A derived method Must call initPVRecord. * @return true for success and false for failure. */ virtual bool init() {initPVRecord(); return true;} /** - * Optional method for derived class. + * @brief Optional method for derived class. + * * It is called before record is added to database. */ virtual void start() {} /** - * Optional method. + * @brief Optional method for derived class. + * * It is the method that makes a record smart. * If it encounters errors it should raise alarms and/or * call the message method provided by the base class. @@ -96,106 +97,17 @@ public: */ virtual void process(); /** - * Destroy the PVRecord. Release any resources used and + * @brief Optional method for derived class. + * + * Destroy the PVRecord. Release any resources used and * get rid of listeners and requesters. * If derived class overrides this then it must call PVRecord::destroy() * after it has destroyed any resorces it uses. */ virtual void destroy(); /** - * Creates a soft record. - * @param recordName The name of the record, which is also the channelName. - * @param pvStructure The top level structure. - * @return A shared pointer to the newly created record. - */ - static PVRecordPtr create( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure); - /** - * Get the name of the record. - * @return The name. - */ - std::string getRecordName() const { return recordName;} - /** - * Get the top level PVRecordStructure. - * @return The shared pointer. - */ - PVRecordStructurePtr getPVRecordStructure() const { return pvRecordStructure;} - /** - * Convenience method for derived classes. - * @return The top level PVStructure. - */ - epics::pvData::PVStructurePtr getPVStructure() const { return pvStructure;} - /** - * Find the PVRecordField for the PVField. - * @param pvField The PVField. - * @return The shared pointer to the PVRecordField. - */ - PVRecordFieldPtr findPVRecordField( - epics::pvData::PVFieldPtr const & pvField); - /** - * Lock the record. - * Any code must lock while accessing a record. - */ - void lock(); - /** - * Unlock the record. - */ - void unlock(); - /** - * If true then just like lock. - * If falseclient can not access record. - * Code can try to simultaneously hold the lock for more than two records - * by calling this method but must be willing to accept failure. - * @return true if the record is locked. - */ - bool tryLock(); - /** - * A client that holds the lock for one record can lock one other record. - * A client must not call this if the client already has the lock for - * more then one record. + * @brief Optional method for derived class. * - * @param otherRecord The other record to lock. - */ - void lockOtherRecord(PVRecordPtr const & otherRecord); - /** - * Every client that accesses the record must call this so that the - * client can be notified when the record is deleted. - * @param pvRecordClient The client. - * @return true if the client is added. - */ - bool addPVRecordClient(PVRecordClientPtr const & pvRecordClient); - /** - * Remove a client. - * @param pvRecordClient The client. - * @return true if the client is removed. - */ - bool removePVRecordClient(PVRecordClientPtr const & pvRecordClient); - /** - * Add a PVListener. - * This must be called before calling pvRecordField.addListener. - * @param pvListener The listener. - * @param pvCopy The pvStructure that has the client fields. - * @return true if the listener was added. - */ - bool addListener( - PVListenerPtr const & pvListener, - epics::pvData::PVCopyPtr const & pvCopy); - /* - * PVCopyTraverseMasterCallback method - * @param pvField The next client field. - */ - void nextMasterPVField(epics::pvData::PVFieldPtr const & pvField); - /** - * Remove a listener. - * @param pvListener The listener. - * @param pvCopy The pvStructure that has the client fields. - * @return true if the listener was removed. - */ - bool removeListener( - PVListenerPtr const & pvListener, - epics::pvData::PVCopyPtr const & pvCopy); - /** * Return a service corresponding to the specified request PVStructure. * @param pvRequest The request PVStructure * @return The corresponding service @@ -205,28 +117,141 @@ public: { return epics::pvAccess::Service::shared_pointer(); } + /** + * @brief Creates a soft record. + * + * @param recordName The name of the record, which is also the channelName. + * @param pvStructure The top level structure. + * @return A shared pointer to the newly created record. + */ + static PVRecordPtr create( + std::string const & recordName, + epics::pvData::PVStructurePtr const & pvStructure); + /** + * @brief Get the name of the record. + * + * @return The name. + */ + std::string getRecordName() const { return recordName;} + /** + * @brief Get the top level PVRecordStructure. + * + * @return The shared pointer. + */ + PVRecordStructurePtr getPVRecordStructure() const { return pvRecordStructure;} + /** + * @brief Get the top level PVStructure. + * + * @return The top level PVStructure. + */ + epics::pvData::PVStructurePtr getPVStructure() const { return pvStructure;} + /** + * @brief Find the PVRecordField for the PVField. + * + * This is called by the pvCopy facility. + * @param pvField The PVField. + * @return The shared pointer to the PVRecordField. + */ + PVRecordFieldPtr findPVRecordField( + epics::pvData::PVFieldPtr const & pvField); + /** + * @brief Lock the record. + * + * Any code must lock while accessing a record. + */ + void lock(); + /** + * @brief Unlock the record. + * + * The code that calls lock must unlock when done accessing the record. + */ + void unlock(); + /** + * @brief Try to lock the record. + * + * If true then just like lock. + * If falseclient can not access record. + * Code can try to simultaneously hold the lock for more than two records + * by calling this method but must be willing to accept failure. + * @return true if the record is locked. + */ + bool tryLock(); + /** + * @brief Lock another record. + * + * A client that holds the lock for one record can lock one other record. + * A client must not call this if the client already has the lock for + * more then one record. + * + * @param otherRecord The other record to lock. + */ + void lockOtherRecord(PVRecordPtr const & otherRecord); + /** + * @brief Add a client that wants to access the record. + * + * Every client that accesses the record must call this so that the + * client can be notified when the record is deleted. + * @param pvRecordClient The client. + * @return true if the client is added. + */ + bool addPVRecordClient(PVRecordClientPtr const & pvRecordClient); + /** + * @brief Remove a client. + * + * @param pvRecordClient The client. + * @return true if the client is removed. + */ + bool removePVRecordClient(PVRecordClientPtr const & pvRecordClient); + /** + * @brief Add a PVListener. + * + * This must be called before calling pvRecordField.addListener. + * @param pvListener The listener. + * @param pvCopy The pvStructure that has the client fields. + * @return true if the listener was added. + */ + bool addListener( + PVListenerPtr const & pvListener, + epics::pvData::PVCopyPtr const & pvCopy); + /** + * @brief PVCopyTraverseMasterCallback method + * + * @param pvField The next client field. + */ + void nextMasterPVField(epics::pvData::PVFieldPtr const & pvField); + /** + * @brief Remove a listener. + * + * @param pvListener The listener. + * @param pvCopy The pvStructure that has the client fields. + * @return true if the listener was removed. + */ + bool removeListener( + PVListenerPtr const & pvListener, + epics::pvData::PVCopyPtr const & pvCopy); + /** - * Begins a group of puts. + * @brief Begins a group of puts. */ void beginGroupPut(); /** - * Ends a group of puts. + * @brief Ends a group of puts. */ void endGroupPut(); /** - * get trace level (0,1,2) means (nothing,lifetime,process) + * @brief get trace level (0,1,2) means (nothing,lifetime,process) * @return the level */ int getTraceLevel() {return traceLevel;} /** - * set trace level (0,1,2) means (nothing,lifetime,process) + * @brief set trace level (0,1,2) means (nothing,lifetime,process) * @param level The level */ void setTraceLevel(int level) {traceLevel = level;} protected: /** - * Constructor + * @brief Constructor * @param recordName The name of the record * @param pvStructure The top level PVStructutre */ @@ -234,10 +259,13 @@ protected: std::string const & recordName, epics::pvData::PVStructurePtr const & pvStructure); /** - * Initializes the base class. Must be called by derived classes. + * @brief Initializes the base class. + * + * Must be called by derived classes. */ void initPVRecord(); - /** Get shared pointer to self + /** + * @brief Get shared pointer to self. * @return The shared pointer. */ PVRecordPtr getPtrSelf() @@ -282,7 +310,8 @@ class epicsShareClass PVRecordField : public: POINTER_DEFINITIONS(PVRecordField); /** - * Constructor. + * @brief Constructor. + * * @param pvField The field from the top level structure. * @param parent The parent. * @param pvRecord The PVRecord. @@ -292,36 +321,38 @@ public: PVRecordStructurePtr const &parent, PVRecordPtr const & pvRecord); /** - * Destructor. + * @brief Destructor. */ virtual ~PVRecordField() {} /** - * Get the parent. + * @brief Get the parent. + * * @return The parent. */ PVRecordStructurePtr getParent(); /** - * Get the PVField. + * @brief Get the PVField. + * * @return The shared pointer. */ epics::pvData::PVFieldPtr getPVField(); /** - * Get the full name of the field, i.e. field,field,.. + * @brief Get the full name of the field, i.e. field,field,.. * @return The full name. */ std::string getFullFieldName(); /** - * Get the recordName plus the full name of the field, i.e. recordName.field,field,.. + * @brief Get the recordName plus the full name of the field, i.e. recordName.field,field,.. * @return The name. */ std::string getFullName(); /** - * Returns the PVRecord to which this field belongs. + * @brief Return the PVRecord to which this field belongs. * @return The shared pointer, */ PVRecordPtr getPVRecord(); /** - * This is called by the code that implements the data interface. + * @brief This is called by the code that implements the data interface. * It is called whenever the put method is called. */ virtual void postPut(); @@ -355,7 +386,7 @@ class epicsShareClass PVRecordStructure : public PVRecordField { public: POINTER_DEFINITIONS(PVRecordStructure); /** - * Constructor. + * @brief Constructor. * @param pvStructure The data. * @param parent The parent * @param pvRecord The record that has this field. @@ -365,22 +396,22 @@ public: PVRecordStructurePtr const &parent, PVRecordPtr const & pvRecord); /** - * Destructor. + * @brief Destructor. */ virtual ~PVRecordStructure() {} /** - * Get the sub fields. + * @brief Get the sub fields. * @return the array of PVRecordFieldPtr. */ PVRecordFieldPtrArrayPtr getPVRecordFields(); /** - * Get the data structure/ + * @brief Get the data structure/ * @return The shared pointer. */ epics::pvData::PVStructurePtr getPVStructure(); protected: /** - * Called by implementation code of PVRecord. + * @brief Called by implementation code of PVRecord. */ virtual void init(); private: @@ -398,11 +429,11 @@ class epicsShareClass PVRecordClient { public: POINTER_DEFINITIONS(PVRecordClient); /** - * Destructor. + * @brief Destructor. */ virtual ~PVRecordClient() {} /** - * Detach from the record because it is being removed. + * @brief Detach from the record because it is being removed. * @param pvRecord The record. */ virtual void detach(PVRecordPtr const & pvRecord) = 0; @@ -420,17 +451,19 @@ class epicsShareClass PVListener : public: POINTER_DEFINITIONS(PVListener); /** - * Destructor. + * @brief Destructor. */ virtual ~PVListener() {} /** - * pvField has been modified. + * @brief pvField has been modified. + * * This is called if the listener has called PVRecordField::addListener for pvRecordField. * @param pvRecordField The modified field. */ virtual void dataPut(PVRecordFieldPtr const & pvRecordField) = 0; /** - * A subfield has been modified. + * @brief A subfield has been modified. + * * @param requested The structure that was requested. * @param pvRecordField The field that was modified. */ @@ -438,17 +471,17 @@ public: PVRecordStructurePtr const & requested, PVRecordFieldPtr const & pvRecordField) = 0; /** - * Begin a set of puts. + * @brief Begin a set of puts. * @param pvRecord The record. */ virtual void beginGroupPut(PVRecordPtr const & pvRecord) = 0; /** - * End a set of puts. + * @brief End a set of puts. * @param pvRecord The record. */ virtual void endGroupPut(PVRecordPtr const & pvRecord) = 0; /** - * Connection to record is being terminated. + * @brief Connection to record is being terminated. * @param pvRecord The record. */ virtual void unlisten(PVRecordPtr const & pvRecord) = 0; @@ -463,16 +496,17 @@ class epicsShareClass PVDatabase { public: POINTER_DEFINITIONS(PVDatabase); /** - * Get the master database. + * @brief Get the master database. * @return The shared pointer. */ static PVDatabasePtr getMaster(); /** - * Destructor + * @brief Destructor */ virtual ~PVDatabase(); /** - * Destroy the PVDatabase. + * @brief Destroy the PVDatabase. + * * For each record in the database the record is removed and it's destroy method is called. */ virtual void destroy(); @@ -484,19 +518,20 @@ public: */ PVRecordPtr findRecord(std::string const& recordName); /** - * Add a record. + * @brief Add a record. + * * @param record The record to add. * @return true if record was added. */ bool addRecord(PVRecordPtr const & record); /** - * Remove a record. + * @brief Remove a record. * @param record The record to remove. * @return true if record was removed. */ bool removeRecord(PVRecordPtr const & record); /** - * Get the names of all the records in the database. + * @brief Get the names of all the records in the database. * @return The names. */ epics::pvData::PVStringArrayPtr getRecordNames(); diff --git a/src/pv/removeRecord.h b/src/pv/removeRecord.h index 95ccb2c..b4f5679 100644 --- a/src/pv/removeRecord.h +++ b/src/pv/removeRecord.h @@ -41,21 +41,13 @@ public: */ static RemoveRecordPtr create( std::string const & recordName); - /** - * destructor - */ - virtual ~RemoveRecord(); - /** - * 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. + * @brief Remove the record specified by recordName. */ virtual void process(); private: diff --git a/src/pv/traceRecord.h b/src/pv/traceRecord.h index 3df7867..eaf5835 100644 --- a/src/pv/traceRecord.h +++ b/src/pv/traceRecord.h @@ -35,27 +35,20 @@ class epicsShareClass TraceRecord : public: POINTER_DEFINITIONS(TraceRecord); /** - * Factory methods to create TraceRecord. + * @brief Factory method 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. + * @brief Set the trace level for record specified by recordName. */ virtual void process(); private: diff --git a/src/special/removeRecord.cpp b/src/special/removeRecord.cpp index 5c48f99..681f74e 100644 --- a/src/special/removeRecord.cpp +++ b/src/special/removeRecord.cpp @@ -47,15 +47,6 @@ RemoveRecord::RemoveRecord( { } -RemoveRecord::~RemoveRecord() -{ -} - -void RemoveRecord::destroy() -{ - PVRecord::destroy(); -} - bool RemoveRecord::init() { initPVRecord(); diff --git a/src/special/traceRecord.cpp b/src/special/traceRecord.cpp index 0794cc2..1b58f77 100644 --- a/src/special/traceRecord.cpp +++ b/src/special/traceRecord.cpp @@ -48,14 +48,6 @@ TraceRecord::TraceRecord( { } -TraceRecord::~TraceRecord() -{ -} - -void TraceRecord::destroy() -{ - PVRecord::destroy(); -} bool TraceRecord::init() {