1) added canRead for access security
2) main documentation moved to https://mrkraimer.github.io/website/developerGuide/pvDatabase/pvDatabaseCPP.html
This commit is contained in:
@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
This document summarizes the changes to the module between releases.
|
This document summarizes the changes to the module between releases.
|
||||||
|
|
||||||
|
## Release 4.6.0 (EPICS 7.0.5.* March 2021)
|
||||||
|
|
||||||
|
* Access Security is now supported.
|
||||||
|
* Special support has been revised and extended.
|
||||||
|
|
||||||
## Release 4.5.3 (EPICS 7.0.5 Feb 2021)
|
## Release 4.5.3 (EPICS 7.0.5 Feb 2021)
|
||||||
|
|
||||||
* The previously deprecated destroy methods have been removed.
|
* The previously deprecated destroy methods have been removed.
|
||||||
|
@ -4,72 +4,66 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
<title>pvDatabaseCPP</title>
|
<title>EPICS pvDatabaseCPP</title>
|
||||||
<link rel="stylesheet" type="text/css"
|
<link rel="stylesheet" type="text/css"
|
||||||
href="http://epics-pvdata.sourceforge.net/base.css" />
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
<link rel="stylesheet" type="text/css"
|
<link rel="stylesheet" type="text/css"
|
||||||
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/*<![CDATA[*/
|
/*<![CDATA[*/
|
||||||
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
table { margin-left: auto; margin-right: auto }
|
table { margin-left: auto; margin-right: auto }
|
||||||
.diagram { text-align: center; margin: 2.5em 0 }
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
span.opt { color: grey }
|
body { margin-right: 10% }
|
||||||
span.nterm { font-style:italic }
|
/*]]>*/</style>
|
||||||
span.term { font-family:courier }
|
|
||||||
span.user { font-family:courier }
|
<!-- Script that generates the Table of Contents -->
|
||||||
span.user:before { content:"<" }
|
<script type="text/javascript" src="http://epics-pvdata.sourceforge.net/script/tocgen.js"></script>
|
||||||
span.user:after { content:">" }
|
|
||||||
.nonnorm { font-style:italic }
|
|
||||||
p.ed { color: #AA0000 }
|
|
||||||
span.ed { color: #AA0000 }
|
|
||||||
p.ed.priv { display: inline; }
|
|
||||||
span.ed.priv { display: inline; }
|
|
||||||
/*]]>*/</style>
|
|
||||||
<!-- Script that generates the Table of Contents -->
|
|
||||||
<script type="text/javascript"
|
|
||||||
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="head">
|
<div class="head">
|
||||||
<h1>pvDatabaseCPP</h1>
|
<h1>EPICS pvDatabaseCPP</h1>
|
||||||
<h2 class="nocount">Release ? - TBD</h2>
|
<h2 class="nocount">Release 4.6.0 - March 2021</h2>
|
||||||
Latest update 2019.09.11.
|
|
||||||
|
|
||||||
|
|
||||||
<h2 class="nocount">Abstract</h2>
|
<h2 class="nocount">Abstract</h2>
|
||||||
|
|
||||||
<p>This document describes pvDatabaseCPP,
|
<p><b>pvDatabase</b> is a framework for implementing a network accessible database of smart memory resident
|
||||||
which is a framework for implementing a network accessible database of smart memory resident
|
|
||||||
records. Network access is via pvAccess. The data in each record is a top level PVStructure as defined by
|
records. Network access is via pvAccess. The data in each record is a top level PVStructure as defined by
|
||||||
pvData. The framework includes a complete implementation of ChannelProvider as defined by pvAccess.
|
pvData. The framework includes a complete implementation of ChannelProvider as defined by pvAccess.
|
||||||
The framework can be extended in order to create record instances that implements services.
|
The framework can be extended in order to create record instances that implements services.
|
||||||
The minimum that an extension must provide is a top level PVStructure and a process method.
|
The minimum that an extension must provide is a top level PVStructure and a process method.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- last para of Abstract is boilerplate reference to EPICS -->
|
<!-- last para of Abstract is boilerplate reference to EPICS -->
|
||||||
<p>For more information about EPICS generally, please refer to the home page of the <a
|
<p>For more information about EPICS generally, please refer to the home page of the <a
|
||||||
href="http://www.aps.anl.gov/epics/">Experimental Physics and Industrial
|
href="http://www.aps.anl.gov/epics/">Experimental Physics and Industrial
|
||||||
Control System</a>.</p>
|
Control System</a>.</p>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div> <!-- head -->
|
||||||
|
|
||||||
<div id="toc">
|
|
||||||
<h2 class="nocount">Table of Contents</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="contents" class="contents">
|
<div id="contents" class="contents">
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<h2>Overview</h2>
|
<h2>Overview</h2>
|
||||||
<p>
|
<p>
|
||||||
|
Documentation for pvDatabaseCPP is available at:
|
||||||
|
<a
|
||||||
|
href="https://mrkraimer.github.io/website/developerGuide/pvDatabase/pvDatabaseCPP.html">
|
||||||
|
pvDatabase
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
pvDatabaseCPP is one of the components of
|
pvDatabaseCPP is one of the components of
|
||||||
EPICS Version 7
|
<a href="https://epics-controls.org/resources-and-support/base/epics-7/">
|
||||||
|
EPICS-7
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>This document is only a guide to help locate code and documentation related to pvDatabaseCPP
|
<p>This document is only a guide to help locate code and documentation related to pvDatabaseCPP
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
It is intended for developers that want to use pvDatabaseCPP.
|
It is intended for developers that want to use pvDatabaseCPP.
|
||||||
</p>
|
</p>
|
||||||
<h2>Developer Guide</h2>
|
<h2>Developer Guide</h2>
|
||||||
@ -79,204 +73,28 @@ href="https://mrkraimer.github.io/website/developerGuide/developerGuide.html">
|
|||||||
developerGuide
|
developerGuide
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>This guide discusses all the components that are part of an <b>EPICS V4</b> release.
|
<p>This guide provides an overview of the components that are part of an <b>EPICS V4</b> release.
|
||||||
Some understanding of the components and how they are related is necessary in order to
|
Some understanding of the components and how they are related is necessary in order to
|
||||||
develop code that uses pvDatabaseCPP.
|
develop code that uses pvDatabaseCPP.
|
||||||
In particular read everything related to pvDatabase.
|
In particular read everything related to pvaClient.
|
||||||
</p>
|
|
||||||
<p>pvDatabase has plugin support, which is implemented in <b>pvCopy</b>.
|
|
||||||
<b>pvCopy</b> was originally implemented in <b>pvDataCPP</b>,
|
|
||||||
but pvDatabaseCPP now implements its own version and adds plugin support.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
See
|
|
||||||
<a
|
|
||||||
href="https://mrkraimer.github.io/website/pvRequest/pvRequest.html">
|
|
||||||
pvRequest
|
|
||||||
</a>
|
|
||||||
for details.
|
|
||||||
</p>
|
|
||||||
<p>The developerGuide discusses code in a way that applies to both CPP and C++.
|
|
||||||
For the descriptions of the CPP specific code consult the following sections.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>doxygen</h2>
|
<h2>doxygen</h2>
|
||||||
<p>doxygen documentation is available at
|
<p>doxygen documentation is available at
|
||||||
<a
|
<a
|
||||||
href="./html/index.html">doxgen</a>
|
href="./html/index.html">doxygen</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>pvDatabaseCPP</h2>
|
|
||||||
<h3>include/pv</h3>
|
|
||||||
<p>The header files that describe the various components implemented by pvDatabase.
|
|
||||||
</p>
|
|
||||||
<dl>
|
|
||||||
<dt>pvDatabase.h</dt>
|
|
||||||
<dd>
|
|
||||||
This describes PVRecord and PVDatabase.
|
|
||||||
</dd>
|
|
||||||
<dt>channelProviderLocal.h </dt>
|
|
||||||
<dd>
|
|
||||||
This describes a channel provider for PVDatabase
|
|
||||||
</dd>
|
|
||||||
<dt>pvSupport.h</dt>
|
|
||||||
<dd>
|
|
||||||
This is the base class for support attached to a field of a record.
|
|
||||||
</dd>
|
|
||||||
<dt>controlSupport.h</dt>
|
|
||||||
<dd>
|
|
||||||
This is support that implements control limits.
|
|
||||||
</dd>
|
|
||||||
<dt>scalarAlarmSupport.h</dt>
|
|
||||||
<dd>
|
|
||||||
This is support for a alarm limits for a scalar numeric field.
|
|
||||||
</dd>
|
|
||||||
<dt>processRecord.h</dt>
|
|
||||||
<dd>
|
|
||||||
This is a PVRecord that periodical processes a set of PVRecords in the local PVDatabase.
|
|
||||||
</dd>
|
|
||||||
<dt>addRecord.h</dt>
|
|
||||||
<dd>
|
|
||||||
This is a PVRecord that adds a new PVRecord to the local PVDatabase.
|
|
||||||
</dd>
|
|
||||||
<dt>removeRecord.h</dt>
|
|
||||||
<dd>
|
|
||||||
This is a PVRecord that removes a PVRecord in the local PVDatabase.
|
|
||||||
</dd>
|
|
||||||
<dt>traceRecord.h</dt>
|
|
||||||
<dd>
|
|
||||||
This is a PVRecord that sets the trace value for another PVRecord in the local PVDatabase.
|
|
||||||
</dd>
|
|
||||||
<dt>pvStructureCopy.h</dt>
|
|
||||||
<dd>
|
|
||||||
This is a facility that allows a client to access a subfield of the fields in a PVRecord.
|
|
||||||
It also provides record and field options an plugin support.
|
|
||||||
</dd>
|
|
||||||
<dt>pvPlugin.h</dt>
|
|
||||||
<dd>
|
|
||||||
This is the base class for a plugin attached to a record or field of PVRecord.
|
|
||||||
</dd>
|
|
||||||
<dt>pvArrayPlugin.h</dt>
|
|
||||||
<dd>
|
|
||||||
A plugin for accessing a subset of the elements in an array field.
|
|
||||||
</dd>
|
|
||||||
<dt>pvDeadbandPlugin.h</dt>
|
|
||||||
<dd>
|
|
||||||
A deadband plugin for monitors.
|
|
||||||
</dd>
|
|
||||||
<dt>pvTimestampPlugin.h</dt>
|
|
||||||
<dd>
|
|
||||||
A plugin for timeStamp.
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
<h3>src/database</h3>
|
|
||||||
<p>This has the code that implements pvDatabase and pvRecord.</p>
|
|
||||||
<h3>src/pvAccess</h3>
|
|
||||||
<p>This has the code for the channel provider for pvDatabase.
|
|
||||||
</p>
|
|
||||||
<h3>src/support</h3>
|
|
||||||
<p>This has the pvSupport code.</p>
|
|
||||||
<h3>src/special</h3>
|
|
||||||
<p>
|
|
||||||
This has the code for processRecord, addRecord, removeRecord, and traceRecord.
|
|
||||||
</p>
|
|
||||||
<h3>src/copy</h3>
|
|
||||||
<p>This has the code for pvStructureCopy and all the plugin support.
|
|
||||||
</p>
|
|
||||||
<h2>exampleCPP</h2>
|
<h2>exampleCPP</h2>
|
||||||
<p>Example code is available as part of this release.
|
<p>Example code is available at
|
||||||
<a
|
<a
|
||||||
href="https://github.com/epics-base/exampleCPP">
|
href="https://github.com/epics-base/exampleCPP">
|
||||||
exampleCPP
|
exampleCPP
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>In particular look at the example code mentioned in the following sub-sections.
|
<p>In particular look at database, exampleLink, and helloPutGet.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3>database</h3>
|
</div> <!-- class="contents" -->
|
||||||
<p>This has many examples of how to create both soft records and records that implement
|
|
||||||
other functionality.</p>
|
|
||||||
<dl>
|
|
||||||
<dt>exampleDatabase.cpp</dt>
|
|
||||||
<dd>
|
|
||||||
This shows how to create soft records of each pvData type.<br />
|
|
||||||
In addition shows how to create instances of the following two records.
|
|
||||||
</dd>
|
|
||||||
<dt>exampleHelloRecord.cpp</dt>
|
|
||||||
<dd>
|
|
||||||
This is a simple "hello world" that is intentended to be used via a channelPutGet request.
|
|
||||||
</dd>
|
|
||||||
<dt>exampleHelloRPC.cpp</dt>
|
|
||||||
<dd>
|
|
||||||
This is a simple "hello world" that is intentended to be used via a channelRPC request.
|
|
||||||
</dd>
|
|
||||||
<dt>exampleDatabaseMain.cpp</dt>
|
|
||||||
<dd>
|
|
||||||
This shows how to create a standalone IOC.
|
|
||||||
</dd>
|
|
||||||
<dt>ioc and iocBoot</dt>
|
|
||||||
<dd>
|
|
||||||
This has code and examples to create a V3 IOC which also has a PVDatabase.
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
<h3>exampleLink</h3>
|
|
||||||
<p>This shows how to implement a record that has a link to another record</p>
|
|
||||||
<dl>
|
|
||||||
<dt>exampleMonitorLinkRecord</dt>
|
|
||||||
<dd>
|
|
||||||
This creates a monitor link to another record.
|
|
||||||
</dd>
|
|
||||||
<dt>exampleGetLinkRecord</dt>
|
|
||||||
<dd>
|
|
||||||
This creates a get link to another record.
|
|
||||||
</dd>
|
|
||||||
<dt>examplePutLinkRecord</dt>
|
|
||||||
<dd>
|
|
||||||
This creates a put link to another record.
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
<h3>support</h3>
|
|
||||||
<p>This creates records that have the following features:</p>
|
|
||||||
<dl>
|
|
||||||
<dt>value</dt>
|
|
||||||
<dd>
|
|
||||||
Each record has a value field the is a numeric scalar field.
|
|
||||||
In addition each has the following fields:
|
|
||||||
alarm,timeStamp,control,scalarAlarm, and display.
|
|
||||||
</dd>
|
|
||||||
<dt>support</dt>
|
|
||||||
<dd>
|
|
||||||
Each record uses the control and scalarAlarm support provided by pvDatabaseCPP.
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
<p>
|
|
||||||
It also creates records that can be used by clients to show example of the plugin support.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>iocshell commands</h2>
|
|
||||||
<p>Shell commands are made available via the standard DBD include mechanism
|
|
||||||
provided by iocCore.
|
|
||||||
The following provide EPICS V4 shell commands:</p>
|
|
||||||
<pre>
|
|
||||||
pvAccessCPP
|
|
||||||
qsrv
|
|
||||||
pvDatabaseCPP
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>pvDatabaseCPP provides the following iocshell command.</p>
|
|
||||||
<dl>
|
|
||||||
<dt>registerChannelProviderLocal</dt>
|
|
||||||
<dd>Including <b>registerChannelProviderLocal.dbd</b> as a dbd file automatically starts provider local
|
|
||||||
and also creates the pvdbl shell command.
|
|
||||||
</dd>
|
|
||||||
<dt>pvdbl</dt>
|
|
||||||
<dd>Provides a list of all the pvRecords in database <b>master</b>
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
<p>In addition any code that implements a PVRecord must implement an ioc command.
|
|
||||||
Look at the examples in <b>exampleCPP/support</b> to see how to implement shell commands.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -362,6 +362,12 @@ public:
|
|||||||
* @return true if client can write
|
* @return true if client can write
|
||||||
*/
|
*/
|
||||||
virtual bool canWrite();
|
virtual bool canWrite();
|
||||||
|
/**
|
||||||
|
* @brief determines if client can read
|
||||||
|
*
|
||||||
|
* @return true if client can read
|
||||||
|
*/
|
||||||
|
virtual bool canRead();
|
||||||
protected:
|
protected:
|
||||||
shared_pointer getPtrSelf()
|
shared_pointer getPtrSelf()
|
||||||
{
|
{
|
||||||
|
@ -328,6 +328,13 @@ void ChannelGetLocal::get()
|
|||||||
{
|
{
|
||||||
ChannelGetRequester::shared_pointer requester = channelGetRequester.lock();
|
ChannelGetRequester::shared_pointer requester = channelGetRequester.lock();
|
||||||
if(!requester) return;
|
if(!requester) return;
|
||||||
|
ChannelLocalPtr channel(channelLocal.lock());
|
||||||
|
if(!channel) throw std::logic_error("channel is deleted");
|
||||||
|
if(!channel->canRead()) {
|
||||||
|
Status status = Status::error("ChannelGet::get is not allowed");
|
||||||
|
requester->getDone(status,getPtrSelf(),PVStructurePtr(),BitSetPtr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
PVRecordPtr pvr(pvRecord.lock());
|
PVRecordPtr pvr(pvRecord.lock());
|
||||||
if(!pvr) throw std::logic_error("pvRecord is deleted");
|
if(!pvr) throw std::logic_error("pvRecord is deleted");
|
||||||
try {
|
try {
|
||||||
@ -489,6 +496,13 @@ void ChannelPutLocal::get()
|
|||||||
{
|
{
|
||||||
ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
|
ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
|
||||||
if(!requester) return;
|
if(!requester) return;
|
||||||
|
ChannelLocalPtr channel(channelLocal.lock());
|
||||||
|
if(!channel) throw std::logic_error("channel is deleted");
|
||||||
|
if(!channel->canRead()) {
|
||||||
|
Status status = Status::error("ChannelPut::get is not allowed");
|
||||||
|
requester->getDone(status,getPtrSelf(),PVStructurePtr(),BitSetPtr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
PVRecordPtr pvr(pvRecord.lock());
|
PVRecordPtr pvr(pvRecord.lock());
|
||||||
if(!pvr) throw std::logic_error("pvRecord is deleted");
|
if(!pvr) throw std::logic_error("pvRecord is deleted");
|
||||||
try {
|
try {
|
||||||
@ -522,7 +536,7 @@ void ChannelPutLocal::put(
|
|||||||
ChannelLocalPtr channel(channelLocal.lock());
|
ChannelLocalPtr channel(channelLocal.lock());
|
||||||
if(!channel) throw std::logic_error("channel is deleted");
|
if(!channel) throw std::logic_error("channel is deleted");
|
||||||
if(!channel->canWrite()) {
|
if(!channel->canWrite()) {
|
||||||
Status status = Status::error("Channel put is not allowed");
|
Status status = Status::error("ChannelPut::put is not allowed");
|
||||||
requester->putDone(status,getPtrSelf());
|
requester->putDone(status,getPtrSelf());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -689,9 +703,9 @@ void ChannelPutGetLocal::putGet(
|
|||||||
if(!requester) return;
|
if(!requester) return;
|
||||||
ChannelLocalPtr channel(channelLocal.lock());
|
ChannelLocalPtr channel(channelLocal.lock());
|
||||||
if(!channel) throw std::logic_error("channel is deleted");
|
if(!channel) throw std::logic_error("channel is deleted");
|
||||||
if(!channel->canWrite()) {
|
if(!channel->canWrite()||!channel->canRead() ) {
|
||||||
Status status = Status::error("Channel putGet is not allowed");
|
Status status = Status::error("ChannelPutGet::putGet is not allowed");
|
||||||
requester->putGetDone(status,getPtrSelf(),pvGetStructure,getBitSet);
|
requester->putGetDone(status,getPtrSelf(),PVStructurePtr(),BitSetPtr());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PVRecordPtr pvr(pvRecord.lock());
|
PVRecordPtr pvr(pvRecord.lock());
|
||||||
@ -722,6 +736,13 @@ void ChannelPutGetLocal::getPut()
|
|||||||
{
|
{
|
||||||
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
|
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
|
||||||
if(!requester) return;
|
if(!requester) return;
|
||||||
|
ChannelLocalPtr channel(channelLocal.lock());
|
||||||
|
if(!channel) throw std::logic_error("channel is deleted");
|
||||||
|
if(!channel->canRead()) {
|
||||||
|
Status status = Status::error("ChannelPutGet::getPut is not allowed");
|
||||||
|
requester->getPutDone(status,getPtrSelf(),PVStructurePtr(),BitSetPtr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
PVRecordPtr pvr(pvRecord.lock());
|
PVRecordPtr pvr(pvRecord.lock());
|
||||||
if(!pvr) throw std::logic_error("pvRecord is deleted");
|
if(!pvr) throw std::logic_error("pvRecord is deleted");
|
||||||
try {
|
try {
|
||||||
@ -749,6 +770,13 @@ void ChannelPutGetLocal::getGet()
|
|||||||
{
|
{
|
||||||
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
|
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
|
||||||
if(!requester) return;
|
if(!requester) return;
|
||||||
|
ChannelLocalPtr channel(channelLocal.lock());
|
||||||
|
if(!channel) throw std::logic_error("channel is deleted");
|
||||||
|
if(!channel->canRead()) {
|
||||||
|
Status status = Status::error("ChannelPutGet::getGet is not allowed");
|
||||||
|
requester->getPutDone(status,getPtrSelf(),PVStructurePtr(),BitSetPtr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
PVRecordPtr pvr(pvRecord.lock());
|
PVRecordPtr pvr(pvRecord.lock());
|
||||||
if(!pvr) throw std::logic_error("pvRecord is deleted");
|
if(!pvr) throw std::logic_error("pvRecord is deleted");
|
||||||
try {
|
try {
|
||||||
@ -1325,9 +1353,15 @@ bool ChannelLocal::canWrite()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChannelLocal::canRead()
|
||||||
|
{
|
||||||
|
if(!asActive || (asClientPvt && asCheckGet(asClientPvt))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
ChannelLocal::~ChannelLocal()
|
ChannelLocal::~ChannelLocal()
|
||||||
{
|
{
|
||||||
// cout << "~ChannelLocal()" << endl;
|
|
||||||
if(asMemberPvt) {
|
if(asMemberPvt) {
|
||||||
asRemoveMember(&asMemberPvt);
|
asRemoveMember(&asMemberPvt);
|
||||||
asMemberPvt = 0;
|
asMemberPvt = 0;
|
||||||
|
Reference in New Issue
Block a user