more work on EasyGet and conneection management; still work in progress
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
<h1>EPICS easyPVA</h1>
|
||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||
<h2 class="nocount">EPICS V4 Working Group, Working Draft,
|
||||
19-Feb-2015</h2>
|
||||
02-Mar-2015</h2>
|
||||
<dl>
|
||||
<dt>This version:</dt>
|
||||
<dd><a
|
||||
@@ -104,20 +104,20 @@ an interface to many of the features provided by pvData and pvAccess.</p>
|
||||
<li>Allows efficient client side programs.</li>
|
||||
</ol>
|
||||
|
||||
<p>The following describes the CPP version of EasyPVA.</p>
|
||||
|
||||
<p>This is the overview for EasyPVACPP. JavaDoc documentation is available at <a
|
||||
<p>This document briefly describes the CPP version of EasyPVA.
|
||||
Doxygen documentation is available at <a
|
||||
href="./html/index.html">doxygenDoc</a></p>
|
||||
|
||||
|
||||
<h3>Initialization</h3>
|
||||
|
||||
<p>A client obtains the interface to EasyPVA via the call:</p>
|
||||
<pre>EasyPVA easy = EasyPVAFactory.get();</pre>
|
||||
<pre>EasyPVAPtr easyPVA = EasyPVAFactorys->create();</pre>
|
||||
|
||||
<p>The client can make this call many times, but an instance of the EastPVA interface object is
|
||||
only created in the first call. This first call also
|
||||
starts the PVAccess client factory.</p>
|
||||
<p>The client can call this an arbitrary number of times.
|
||||
On the first call the PVAccess client factory is started.
|
||||
When the last EasyPVA is destroyed the PVAccess client factory is stopped.
|
||||
</p>
|
||||
|
||||
<h3>EasyPVA Overview</h3>
|
||||
|
||||
@@ -139,13 +139,6 @@ starts the PVAccess client factory.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<p>There are additional methods that allows the client to:</p>
|
||||
<ol>
|
||||
<li>Control how error messages are handled.</li>
|
||||
<li>Control when get/put commands are sent the channel or channels.</li>
|
||||
</ol>
|
||||
|
||||
<h3>EasyChannel Overview</h3>
|
||||
|
||||
<p>This interface creates Easy support for each PVAccess::Channel create
|
||||
@@ -208,15 +201,17 @@ The only requirement of the channels is that each must have a top level field na
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2>shell</h2>
|
||||
<p>Directory <b>shell</b> has the following files:</p>
|
||||
<dl>
|
||||
<dt>exampleDatabaseEasyPVA.zip</dt>
|
||||
<dd>
|
||||
When unzipped this is used to create an example IOC database.
|
||||
The database has the record used by the examples are tests that come with easyPVAJava.
|
||||
It uses pvDatabaseCPP to build the database.
|
||||
After unzipping the file:
|
||||
<h2>example source code</h2>
|
||||
<h3>Example Database</h3>
|
||||
<p>The examples require that an example pvAccess server is runnimg.
|
||||
This distribution has a file <b>exampleDatabaseEasyPVA.zip</b>.
|
||||
When unzipped this is used to create an example IOC database.
|
||||
The database has the record used by the examples are tests that come with easyPVAJava.
|
||||
It uses pvDatabaseCPP to build the database.
|
||||
</p>
|
||||
<p>
|
||||
After unzipping the file:
|
||||
</p>
|
||||
<pre>
|
||||
cd configure
|
||||
cp ExampleRELEASE.local RELEASE.local
|
||||
@@ -226,68 +221,16 @@ make
|
||||
cd iocBoot/exampleDatabase
|
||||
../../bin/<arch:>/exampleDatabase st.cmd
|
||||
</pre>
|
||||
You now have a running database.
|
||||
</dd>
|
||||
<dt>source</dt>
|
||||
<dd>
|
||||
This file creates the <b>CLASSPATH</b> required
|
||||
to run the examples and tests.
|
||||
You have to edit it for your environment.
|
||||
</dd>
|
||||
<dt>rpcServiceExample</dt>
|
||||
<dd>
|
||||
This starts the RPCServiceExample.
|
||||
This is required by ExampleEasyRPC.
|
||||
</dd>
|
||||
<dt>exampleGet</dt>
|
||||
<dd>
|
||||
This runs ExampleGet.
|
||||
</dd>
|
||||
<dt>exampleGetDouble</dt>
|
||||
<dd>
|
||||
This runs ExampleGetDouble
|
||||
</dd>
|
||||
<dt>doublePut</dt>
|
||||
<dd>
|
||||
This runs DoublePut.
|
||||
</dd>
|
||||
<dt>doubleArrayPut</dt>
|
||||
<dd>
|
||||
This runs DoubleArrayPut
|
||||
</dd>
|
||||
<dt>exampleMonitor</dt>
|
||||
<dd>
|
||||
This runs ExampleMonitor
|
||||
</dd>
|
||||
<dt>exampleMonitorCallback</dt>
|
||||
<dd>
|
||||
This runs ExampleMonitorCallback
|
||||
</dd>
|
||||
<dt>exampleMultiMonitor</dt>
|
||||
<dd>
|
||||
This runs ExampleMultiMonitor.
|
||||
It and polls every few seconds for monitor events.
|
||||
It gets data as NTMultiChannel.
|
||||
</dd>
|
||||
<dt>exampleMultiMonitorDouble</dt>
|
||||
<dd>
|
||||
This runs ExampleMultiMonitorDouble.
|
||||
It has an event listener for new events.
|
||||
It gets data as an array of doubles.
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Examples</h3>
|
||||
<p>These are examples in package <b>org.epics.pvaccess.easyPVA.example</b>
|
||||
<p>These are examples in directory <b>example/src</b>.
|
||||
An example of how to run them is:</p>
|
||||
<pre>
|
||||
mrk> pwd
|
||||
/home/hg/easyPVACPP/example
|
||||
mrk> bin/linux-x86_64/exampleEasyGet
|
||||
</pre>
|
||||
<p>
|
||||
See the source code for each example.
|
||||
In order to run the examples exampleDatabaseEasyPVA must be running.
|
||||
</p>
|
||||
<p>There is a shell command to run each example,</p>
|
||||
<h3>Tests</h3>
|
||||
<p>A test directory has a number of tests for easyPVAJava.
|
||||
In order to run the tests both exampleDatabaseEasyPVA and rpcServiceExample
|
||||
must be running.
|
||||
For now these tests are being run as eclipse unit tests.
|
||||
The tests also provide examples of using EasyPVA.
|
||||
</p>
|
||||
|
||||
</div> <!-- class="contents" -->
|
||||
|
||||
@@ -13,18 +13,17 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <pv/easyPVA.h>
|
||||
#include <pv/clientFactory.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
ClientFactory::start();
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
static EasyPVAPtr easyPVA;
|
||||
|
||||
static void exampleDouble()
|
||||
{
|
||||
cout << "example double scalar\n";
|
||||
double value;
|
||||
try {
|
||||
cout << "short way\n";
|
||||
@@ -43,7 +42,52 @@ int main(int argc,char *argv[])
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void exampleDoubleArray()
|
||||
{
|
||||
cout << "example double array\n";
|
||||
shared_vector<double> value;
|
||||
try {
|
||||
cout << "short way\n";
|
||||
value = easyPVA->createChannel("exampleDoubleArray")->createGet()->getDoubleArray();
|
||||
cout << "as doubleArray " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "long way\n";
|
||||
EasyChannelPtr easyChannel = easyPVA->createChannel("exampleDoubleArray");
|
||||
easyChannel->connect(2.0);
|
||||
EasyGetPtr easyGet = easyChannel->createGet();
|
||||
value = easyGet->getDoubleArray();
|
||||
cout << "as doubleArray " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void examplePowerSupply()
|
||||
{
|
||||
cout << "example powerSupply\n";
|
||||
PVStructurePtr pvStructure;
|
||||
try {
|
||||
cout << "short way\n";
|
||||
pvStructure = easyPVA->createChannel("examplePowerSupply")->createGet("field()")->getPVStructure();
|
||||
cout << pvStructure << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
easyPVA = EasyPVA::create();
|
||||
exampleDouble();
|
||||
exampleDoubleArray();
|
||||
examplePowerSupply();
|
||||
cout << "done\n";
|
||||
ClientFactory::stop();
|
||||
easyPVA->destroy();
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
exampleDatabaseEasyPVA.zip
Normal file
BIN
exampleDatabaseEasyPVA.zip
Normal file
Binary file not shown.
@@ -143,19 +143,23 @@ EasyChannelImpl::~EasyChannelImpl()
|
||||
void EasyChannelImpl::channelCreated(const Status& status, Channel::shared_pointer const & channel)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
channelConnectStatus = status;
|
||||
this->channel = channel;
|
||||
if(status.isOK()) {
|
||||
this->channel = channel;
|
||||
return;
|
||||
}
|
||||
cout << "EasyChannelImpl::channelCreated status " << status.getMessage() << " why??\n";
|
||||
}
|
||||
|
||||
void EasyChannelImpl::channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
if(isDestroyed) return;
|
||||
bool waitingForConnect = false;
|
||||
if(connectState==connectActive) waitingForConnect = true;
|
||||
if(connectionState!=Channel::CONNECTED) {
|
||||
string mess(channelName + " connection state " + Channel::ConnectionStateNames[connectionState]);
|
||||
string mess(channelName +
|
||||
" connection state " + Channel::ConnectionStateNames[connectionState]);
|
||||
message(mess,errorMessage);
|
||||
channelConnectStatus = Status(Status::STATUSTYPE_ERROR,mess);
|
||||
connectState = notConnected;
|
||||
@@ -220,10 +224,14 @@ void EasyChannelImpl::issueConnect()
|
||||
}
|
||||
channelRequester = ChannelRequester::shared_pointer(new ChannelRequesterImpl(this));
|
||||
|
||||
channelConnectStatus = Status(Status::STATUSTYPE_ERROR,"createChannel failed");
|
||||
connectState = connectActive;
|
||||
ChannelProviderRegistry::shared_pointer reg = getChannelProviderRegistry();
|
||||
ChannelProvider::shared_pointer provider = reg->getProvider(providerName);
|
||||
channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT);
|
||||
if(!channel) {
|
||||
throw std::runtime_error(channelConnectStatus.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
Status EasyChannelImpl::waitConnect(double timeout)
|
||||
@@ -268,7 +276,7 @@ EasyProcessPtr EasyChannelImpl::createProcess(PVStructurePtr const & pvRequest)
|
||||
|
||||
EasyGetPtr EasyChannelImpl::createGet()
|
||||
{
|
||||
return EasyChannelImpl::createGet("value,alarm.timeStamp");
|
||||
return EasyChannelImpl::createGet("value,alarm,timeStamp");
|
||||
}
|
||||
|
||||
EasyGetPtr EasyChannelImpl::createGet(string const & request)
|
||||
|
||||
@@ -101,6 +101,7 @@ public:
|
||||
return shared_from_this();
|
||||
}
|
||||
private:
|
||||
void checkGetState();
|
||||
enum GetConnectState {connectIdle,connectActive,connected};
|
||||
|
||||
EasyPVAPtr easyPVA;
|
||||
@@ -176,6 +177,12 @@ EasyGetImpl::~EasyGetImpl()
|
||||
destroy();
|
||||
}
|
||||
|
||||
void EasyGetImpl::checkGetState()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
if(getState==getIdle) get();
|
||||
}
|
||||
|
||||
// from ChannelGetRequester
|
||||
string EasyGetImpl::getRequesterName()
|
||||
@@ -257,7 +264,6 @@ void EasyGetImpl::issueConnect()
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
getRequester = ChannelGetRequester::shared_pointer(new ChannelGetRequesterImpl(this));
|
||||
|
||||
connectState = connectActive;
|
||||
channelGet = channel->createChannelGet(getRequester,pvRequest);
|
||||
}
|
||||
@@ -335,206 +341,206 @@ void EasyGetImpl::setPVStructure(epics::pvData::PVStructurePtr const & pvStructu
|
||||
|
||||
Alarm EasyGetImpl::getAlarm()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getAlarm();
|
||||
}
|
||||
|
||||
TimeStamp EasyGetImpl::getTimeStamp()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getTimeStamp();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::hasValue()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->hasValue();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::isValueScalar()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->isValueScalar();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::isValueScalarArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->isValueScalarArray();
|
||||
}
|
||||
|
||||
PVFieldPtr EasyGetImpl::getValue()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getValue();
|
||||
}
|
||||
|
||||
PVScalarPtr EasyGetImpl::getScalarValue()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getScalarValue();
|
||||
}
|
||||
|
||||
std::tr1::shared_ptr<PVArray> EasyGetImpl::getArrayValue()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getArrayValue();
|
||||
}
|
||||
|
||||
std::tr1::shared_ptr<PVScalarArray> EasyGetImpl::getScalarArrayValue()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getScalarArrayValue();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::getBoolean()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getBoolean();
|
||||
}
|
||||
|
||||
int8 EasyGetImpl::getByte()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getByte();
|
||||
}
|
||||
|
||||
int16 EasyGetImpl::getShort()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getShort();
|
||||
}
|
||||
|
||||
int32 EasyGetImpl::getInt()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getInt();
|
||||
}
|
||||
|
||||
int64 EasyGetImpl::getLong()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getLong();
|
||||
}
|
||||
|
||||
uint8 EasyGetImpl::getUByte()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getUByte();
|
||||
}
|
||||
|
||||
uint16 EasyGetImpl::getUShort()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getUShort();
|
||||
}
|
||||
|
||||
uint32 EasyGetImpl::getUInt()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getUInt();
|
||||
}
|
||||
|
||||
uint64 EasyGetImpl::getULong()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getULong();
|
||||
}
|
||||
|
||||
float EasyGetImpl::getFloat()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getFloat();
|
||||
}
|
||||
|
||||
double EasyGetImpl::getDouble()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return easyPVStructure->isValueScalar();
|
||||
checkGetState();
|
||||
return easyPVStructure->getDouble();
|
||||
}
|
||||
|
||||
std::string EasyGetImpl::getString()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getString();
|
||||
}
|
||||
|
||||
|
||||
shared_vector<boolean> EasyGetImpl::getBooleanArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getBooleanArray();
|
||||
}
|
||||
|
||||
shared_vector<int8> EasyGetImpl::getByteArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getByteArray();
|
||||
}
|
||||
|
||||
shared_vector<int16> EasyGetImpl::getShortArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getShortArray();
|
||||
}
|
||||
|
||||
shared_vector<int32> EasyGetImpl::getIntArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getIntArray();
|
||||
}
|
||||
|
||||
shared_vector<int64> EasyGetImpl::getLongArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getLongArray();
|
||||
}
|
||||
|
||||
shared_vector<uint8> EasyGetImpl::getUByteArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getUByteArray();
|
||||
}
|
||||
|
||||
shared_vector<uint16> EasyGetImpl::getUShortArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getUShortArray();
|
||||
}
|
||||
|
||||
shared_vector<uint32> EasyGetImpl::getUIntArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getUIntArray();
|
||||
}
|
||||
|
||||
shared_vector<uint64> EasyGetImpl::getULongArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getULongArray();
|
||||
}
|
||||
|
||||
shared_vector<float> EasyGetImpl::getFloatArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getFloatArray();
|
||||
}
|
||||
|
||||
shared_vector<double> EasyGetImpl::getDoubleArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getDoubleArray();
|
||||
}
|
||||
|
||||
shared_vector<std::string> EasyGetImpl::getStringArray()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getStringArray();
|
||||
}
|
||||
|
||||
PVStructurePtr EasyGetImpl::getPVStructure()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
checkGetState();
|
||||
return easyPVStructure->getPVStructure();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/easyPVA.h>
|
||||
#include <pv/createRequest.h>
|
||||
#include <pv/clientFactory.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
@@ -24,9 +25,46 @@ static const string easyPVAName = "easyPVA";
|
||||
static const string defaultProvider = "pva";
|
||||
static UnionConstPtr variantUnion = fieldCreate->createVariantUnion();
|
||||
|
||||
namespace easyPVAPvt {
|
||||
|
||||
static size_t numberEasyPVA = 0;
|
||||
static bool firstTime = true;
|
||||
static Mutex mutex;
|
||||
|
||||
class StartStopClientFactory {
|
||||
|
||||
public:
|
||||
static void EasyPVABeingConstructed()
|
||||
{
|
||||
bool saveFirst = false;
|
||||
{
|
||||
Lock xx(mutex);
|
||||
++numberEasyPVA;
|
||||
saveFirst = firstTime;
|
||||
firstTime = false;
|
||||
}
|
||||
if(saveFirst) ClientFactory::start();
|
||||
}
|
||||
|
||||
static void EasyPVABeingDestroyed() {
|
||||
size_t numLeft = 0;
|
||||
{
|
||||
Lock xx(mutex);
|
||||
--numberEasyPVA;
|
||||
numLeft = numberEasyPVA;
|
||||
}
|
||||
if(numLeft<=0) ClientFactory::stop();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
using namespace epics::easyPVA::easyPVAPvt;
|
||||
|
||||
|
||||
EasyPVAPtr EasyPVA::create()
|
||||
{
|
||||
EasyPVAPtr xx(new EasyPVA());
|
||||
StartStopClientFactory::EasyPVABeingConstructed();
|
||||
return xx;
|
||||
}
|
||||
|
||||
@@ -45,7 +83,9 @@ EasyPVA::EasyPVA()
|
||||
{
|
||||
}
|
||||
|
||||
EasyPVA::~EasyPVA() {destroy();}
|
||||
EasyPVA::~EasyPVA() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void EasyPVA::destroy()
|
||||
{
|
||||
@@ -61,8 +101,8 @@ void EasyPVA::destroy()
|
||||
channelList.erase(channelIter);
|
||||
(*channelIter)->destroy();
|
||||
}
|
||||
std::list<EasyMultiChannelPtr>::iterator multiChannelIter;
|
||||
#ifdef NOTDONE
|
||||
std::list<EasyMultiChannelPtr>::iterator multiChannelIter;
|
||||
while(true) {
|
||||
multiChannelIter = multiChannelList.begin();
|
||||
if(multiChannelIter==multiChannelList.end()) break;
|
||||
@@ -70,7 +110,7 @@ void EasyPVA::destroy()
|
||||
(*multiChannelIter)->destroy();
|
||||
}
|
||||
#endif
|
||||
|
||||
StartStopClientFactory::EasyPVABeingDestroyed();
|
||||
}
|
||||
|
||||
string EasyPVA:: getRequesterName()
|
||||
|
||||
Reference in New Issue
Block a user