pvaTestClient rename Test* -> pvac::*

This commit is contained in:
Michael Davidsaver
2017-07-14 16:31:18 +02:00
parent 6370f11cd2
commit 32d54569c3
10 changed files with 214 additions and 182 deletions

View File

@ -40,16 +40,16 @@ void alldone(int num)
}
#endif
struct Getter : public TestClientChannel::GetCallback,
public TestClientChannel::ConnectCallback
struct Getter : public pvac::ClientChannel::GetCallback,
public pvac::ClientChannel::ConnectCallback
{
POINTER_DEFINITIONS(Getter);
const std::string name;
TestClientChannel channel;
TestOperation op;
pvac::ClientChannel channel;
pvac::Operation op;
Getter(TestClientProvider& provider, const std::string& name)
Getter(pvac::ClientProvider& provider, const std::string& name)
:name(name)
,channel(provider.connect(name))
{
@ -61,16 +61,16 @@ struct Getter : public TestClientChannel::GetCallback,
op.cancel();
}
virtual void getDone(const TestGetEvent& event)
virtual void getDone(const pvac::GetEvent& event)
{
switch(event.event) {
case TestGetEvent::Fail:
case pvac::GetEvent::Fail:
std::cout<<"Error "<<name<<" : "<<event.message<<"\n";
break;
case TestGetEvent::Cancel:
case pvac::GetEvent::Cancel:
std::cout<<"Cancel "<<name<<"\n";
break;
case TestGetEvent::Success:
case pvac::GetEvent::Success:
pvd::PVField::const_shared_pointer valfld(event.value->getSubField("value"));
if(!valfld)
valfld = event.value;
@ -79,7 +79,7 @@ struct Getter : public TestClientChannel::GetCallback,
}
}
virtual void connectEvent(const TestConnectEvent& evt)
virtual void connectEvent(const pvac::ConnectEvent& evt)
{
if(evt.connected) {
op = channel.get(this);
@ -144,7 +144,7 @@ int main(int argc, char *argv[]) {
pva::ca::CAClientFactory::start();
std::cout<<"Use provider: "<<providerName<<"\n";
TestClientProvider provider(providerName, conf);
pvac::ClientProvider provider(providerName, conf);
// need to store references to keep get (and channel) from being closed
typedef std::set<Getter::shared_pointer> gets_t;

View File

@ -19,9 +19,9 @@ int main(int argc, char *argv[])
epics::pvAccess::ClientFactory::start();
TestClientProvider provider("pva");
pvac::ClientProvider provider("pva");
TestClientChannel channel(provider.connect(argv[1]));
pvac::ClientChannel channel(provider.connect(argv[1]));
std::cout<<channel.name()<<" : "<<channel.get()<<"\n";

View File

@ -35,7 +35,7 @@ typedef epicsGuardRelease<epicsMutex> UnGuard;
struct Worker {
virtual ~Worker() {}
virtual void process(const TestMonitorEvent& event) =0;
virtual void process(const pvac::MonitorEvent& event) =0;
};
// simple work queue with thread.
@ -46,7 +46,7 @@ struct WorkQueue : public epicsThreadRunable {
typedef std::tr1::weak_ptr<Worker> weak_type;
// work queue holds only weak_ptr
// so jobs must be kept alive seperately
typedef std::deque<std::pair<weak_type, TestMonitorEvent> > queue_t;
typedef std::deque<std::pair<weak_type, pvac::MonitorEvent> > queue_t;
queue_t queue;
epicsEvent event;
bool running;
@ -71,7 +71,7 @@ struct WorkQueue : public epicsThreadRunable {
worker.exitWait();
}
void push(const weak_type& cb, const TestMonitorEvent& evt)
void push(const weak_type& cb, const pvac::MonitorEvent& evt)
{
bool wake;
{
@ -123,7 +123,7 @@ void sigdone(int num)
}
#endif
struct MonTracker : public TestClientChannel::MonitorCallback,
struct MonTracker : public pvac::ClientChannel::MonitorCallback,
public Worker,
public std::tr1::enable_shared_from_this<MonTracker>
{
@ -133,12 +133,12 @@ struct MonTracker : public TestClientChannel::MonitorCallback,
virtual ~MonTracker() {mon.cancel();}
const std::string name;
TestMonitor mon;
pvac::Monitor mon;
virtual void monitorEvent(const TestMonitorEvent& evt) OVERRIDE FINAL
virtual void monitorEvent(const pvac::MonitorEvent& evt) OVERRIDE FINAL
{
// shared_from_this() will fail as Cancel is delivered in our dtor.
if(evt.event==TestMonitorEvent::Cancel) return;
if(evt.event==pvac::MonitorEvent::Cancel) return;
// running on internal provider worker thread
// minimize work here.
@ -146,20 +146,20 @@ struct MonTracker : public TestClientChannel::MonitorCallback,
monwork.push(shared_from_this(), evt);
}
virtual void process(const TestMonitorEvent& evt) OVERRIDE FINAL
virtual void process(const pvac::MonitorEvent& evt) OVERRIDE FINAL
{
// running on our worker thread
switch(evt.event) {
case TestMonitorEvent::Fail:
case pvac::MonitorEvent::Fail:
std::cout<<"Error "<<name<<" "<<evt.message<<"\n";
break;
case TestMonitorEvent::Cancel:
case pvac::MonitorEvent::Cancel:
std::cout<<"Cancel "<<name<<"\n";
break;
case TestMonitorEvent::Disconnect:
case pvac::MonitorEvent::Disconnect:
std::cout<<"Disconnect "<<name<<"\n";
break;
case TestMonitorEvent::Data:
case pvac::MonitorEvent::Data:
{
unsigned n;
for(n=0; n<2 && mon.poll(); n++) {
@ -244,7 +244,7 @@ int main(int argc, char *argv[]) {
pva::ca::CAClientFactory::start();
std::cout<<"Use provider: "<<providerName<<"\n";
TestClientProvider provider(providerName, conf);
pvac::ClientProvider provider(providerName, conf);
std::vector<MonTracker::shared_pointer> monitors;
@ -258,7 +258,7 @@ int main(int argc, char *argv[]) {
MonTracker::shared_pointer mon(new MonTracker(pv));
TestClientChannel chan(provider.connect(pv));
pvac::ClientChannel chan(provider.connect(pv));
mon->mon = chan.monitor(mon.get());

View File

@ -47,14 +47,14 @@ void alldone(int num)
}
#endif
struct PutTracker : public TestClientChannel::PutCallback
struct PutTracker : public pvac::ClientChannel::PutCallback
{
POINTER_DEFINITIONS(PutTracker);
TestOperation op;
pvac::Operation op;
const std::string value;
PutTracker(TestClientChannel& channel,
PutTracker(pvac::ClientChannel& channel,
const pvd::PVStructure::const_shared_pointer& pvReq,
const std::string& value)
:op(channel.put(this, pvReq)) // put() starts here
@ -66,7 +66,7 @@ struct PutTracker : public TestClientChannel::PutCallback
op.cancel();
}
virtual void putBuild(const epics::pvData::StructureConstPtr &build, TestClientChannel::PutCallback::Args& args) OVERRIDE FINAL
virtual void putBuild(const epics::pvData::StructureConstPtr &build, pvac::ClientChannel::PutCallback::Args& args) OVERRIDE FINAL
{
// At this point we have the user provided value string 'value'
// and the server provided structure (with types).
@ -92,16 +92,16 @@ struct PutTracker : public TestClientChannel::PutCallback
std::cout<<"Put value "<<valfld<<" sending="<<args.tosend<<"\n";
}
virtual void putDone(const TestPutEvent &evt) OVERRIDE FINAL
virtual void putDone(const pvac::PutEvent &evt) OVERRIDE FINAL
{
switch(evt.event) {
case TestPutEvent::Fail:
case pvac::PutEvent::Fail:
std::cerr<<op.name()<<" Error: "<<evt.message<<"\n";
break;
case TestPutEvent::Cancel:
case pvac::PutEvent::Cancel:
std::cerr<<op.name()<<" Cancelled\n";
break;
case TestPutEvent::Success:
case pvac::PutEvent::Success:
std::cout<<op.name()<<" Done\n";
}
{
@ -188,7 +188,7 @@ int main(int argc, char *argv[]) {
pva::ca::CAClientFactory::start();
std::cout<<"Use provider: "<<providerName<<"\n";
TestClientProvider provider(providerName, conf);
pvac::ClientProvider provider(providerName, conf);
std::vector<PutTracker::shared_pointer> ops(args.size());
@ -201,7 +201,7 @@ int main(int argc, char *argv[]) {
{
args_t::const_reference arg = args[i];
TestClientChannel chan(provider.connect(arg.first));
pvac::ClientChannel chan(provider.connect(arg.first));
PutTracker::shared_pointer op(new PutTracker(chan, pvReq, arg.second));

View File

@ -19,10 +19,18 @@ class Monitor;
class Configuration;
}}//namespace epics::pvAccess
class TestClientProvider;
//! See @ref pvac API
namespace pvac {
//! Information on get/put/rpc completion
struct epicsShareClass TestOperation
/** @defgroup pvac PVAccess Client
*
* @{
*/
class ClientProvider;
//! Handle for in-progress get/put/rpc operation
struct epicsShareClass Operation
{
struct Impl
{
@ -31,9 +39,9 @@ struct epicsShareClass TestOperation
virtual void cancel() =0;
};
TestOperation() {}
TestOperation(const std::tr1::shared_ptr<Impl>&);
~TestOperation();
Operation() {}
Operation(const std::tr1::shared_ptr<Impl>&);
~Operation();
//! Channel name
std::string name() const;
//! Immediate cancellation.
@ -45,7 +53,7 @@ protected:
};
//! Information on put completion
struct epicsShareClass TestPutEvent
struct epicsShareClass PutEvent
{
enum event_t {
Fail, //!< request ends in failure. Check message
@ -57,19 +65,19 @@ struct epicsShareClass TestPutEvent
};
//! Information on get/rpc completion
struct epicsShareClass TestGetEvent : public TestPutEvent
struct epicsShareClass GetEvent : public PutEvent
{
//! New data. NULL unless event==Success
epics::pvData::PVStructure::const_shared_pointer value;
};
//! Handle for monitor subscription
struct epicsShareClass TestMonitor
struct epicsShareClass Monitor
{
struct Impl;
TestMonitor() {}
TestMonitor(const std::tr1::shared_ptr<Impl>&);
~TestMonitor();
Monitor() {}
Monitor(const std::tr1::shared_ptr<Impl>&);
~Monitor();
//! Channel name
std::string name() const;
@ -90,37 +98,37 @@ protected:
};
//! Information on monitor subscription/queue change
struct epicsShareClass TestMonitorEvent
struct epicsShareClass MonitorEvent
{
enum event_t {
Fail=1, //!< subscription ends in an error
Cancel=2, //!< subscription ends in cancellation
Disconnect=4,//!< subscription interrupted to do lose of communication
Data=8, //!< Data queue not empty. Call TestMonitor::poll()
Data=8, //!< Data queue not empty. Call Monitor::poll()
} event;
std::string message; // set for event=Fail
void *priv;
};
//! informaiton on connect/disconnect
struct epicsShareClass TestConnectEvent
struct epicsShareClass ConnectEvent
{
bool connected;
};
struct epicsShareClass TestTimeout : public std::runtime_error
struct epicsShareClass Timeout : public std::runtime_error
{
TestTimeout();
Timeout();
};
//! Represents a single channel
class epicsShareClass TestClientChannel
class epicsShareClass ClientChannel
{
struct Impl;
std::tr1::shared_ptr<Impl> impl;
friend class TestClientProvider;
friend class ClientProvider;
TestClientChannel(const std::tr1::shared_ptr<Impl>& i) :impl(i) {}
ClientChannel(const std::tr1::shared_ptr<Impl>& i) :impl(i) {}
public:
struct epicsShareClass Options {
short priority;
@ -129,35 +137,35 @@ public:
bool operator<(const Options&) const;
};
TestClientChannel() {}
TestClientChannel(const std::tr1::shared_ptr<epics::pvAccess::ChannelProvider>& provider,
ClientChannel() {}
ClientChannel(const std::tr1::shared_ptr<epics::pvAccess::ChannelProvider>& provider,
const std::string& name,
const Options& opt = Options());
~TestClientChannel();
~ClientChannel();
std::string name() const;
//! callback for get() and rpc()
struct epicsShareClass GetCallback {
virtual ~GetCallback() {}
virtual void getDone(const TestGetEvent& evt)=0;
virtual void getDone(const GetEvent& evt)=0;
};
//! Issue request to retrieve current PV value
//! @param cb Completion notification callback. Must outlive TestOperation (call TestOperation::cancel() to force release)
TestOperation get(GetCallback* cb,
//! @param cb Completion notification callback. Must outlive Operation (call Operation::cancel() to force release)
Operation get(GetCallback* cb,
epics::pvData::PVStructure::const_shared_pointer pvRequest = epics::pvData::PVStructure::const_shared_pointer());
//! Block and retrieve current PV value
//! @throws TestTimeout or std::runtime_error
//! @throws Timeout or std::runtime_error
epics::pvData::PVStructure::const_shared_pointer
get(double timeout = 3.0,
epics::pvData::PVStructure::const_shared_pointer pvRequest = epics::pvData::PVStructure::const_shared_pointer());
//! Start an RPC call
//! @param cb Completion notification callback. Must outlive TestOperation (call TestOperation::cancel() to force release)
TestOperation rpc(GetCallback* cb,
//! @param cb Completion notification callback. Must outlive Operation (call Operation::cancel() to force release)
Operation rpc(GetCallback* cb,
const epics::pvData::PVStructure::const_shared_pointer& arguments,
epics::pvData::PVStructure::const_shared_pointer pvRequest = epics::pvData::PVStructure::const_shared_pointer());
@ -176,32 +184,32 @@ public:
};
//! Called to build the value to be sent once the type info is known
virtual void putBuild(const epics::pvData::StructureConstPtr& build, Args& args) =0;
virtual void putDone(const TestPutEvent& evt)=0;
virtual void putDone(const PutEvent& evt)=0;
};
//! Initiate request to change PV
//! @param cb Completion notification callback. Must outlive TestOperation (call TestOperation::cancel() to force release)
//! @param cb Completion notification callback. Must outlive Operation (call Operation::cancel() to force release)
//! TODO: produce bitset to mask fields being set
TestOperation put(PutCallback* cb,
Operation put(PutCallback* cb,
epics::pvData::PVStructure::const_shared_pointer pvRequest = epics::pvData::PVStructure::const_shared_pointer());
struct epicsShareClass MonitorCallback {
virtual ~MonitorCallback() {}
virtual void monitorEvent(const TestMonitorEvent& evt)=0;
virtual void monitorEvent(const MonitorEvent& evt)=0;
};
//! Begin subscription
//! @param cb Completion notification callback. Must outlive TestOperation (call TestOperation::cancel() to force release)
TestMonitor monitor(MonitorCallback *cb,
//! @param cb Completion notification callback. Must outlive Operation (call Operation::cancel() to force release)
Monitor monitor(MonitorCallback *cb,
epics::pvData::PVStructure::const_shared_pointer pvRequest = epics::pvData::PVStructure::const_shared_pointer());
//! Connection state change CB
struct epicsShareClass ConnectCallback {
virtual ~ConnectCallback() {}
virtual void connectEvent(const TestConnectEvent& evt)=0;
virtual void connectEvent(const ConnectEvent& evt)=0;
};
//! Append to list of listeners
//! @param cb Channel dis/connect notification callback. Must outlive TestClientChannel or call to removeConnectListener()
//! @param cb Channel dis/connect notification callback. Must outlive ClientChannel or call to removeConnectListener()
void addConnectListener(ConnectCallback*);
//! Remove from list of listeners
void removeConnectListener(ConnectCallback*);
@ -211,29 +219,33 @@ private:
};
//! Central client context.
class epicsShareClass TestClientProvider
class epicsShareClass ClientProvider
{
struct Impl;
std::tr1::shared_ptr<Impl> impl;
public:
TestClientProvider(const std::string& providerName,
ClientProvider(const std::string& providerName,
const std::tr1::shared_ptr<epics::pvAccess::Configuration>& conf = std::tr1::shared_ptr<epics::pvAccess::Configuration>());
~TestClientProvider();
~ClientProvider();
//! Get a new Channel
//! Does not block.
//! Never returns NULL.
//! Uses internal Channel cache.
TestClientChannel connect(const std::string& name,
const TestClientChannel::Options& conf = TestClientChannel::Options());
ClientChannel connect(const std::string& name,
const ClientChannel::Options& conf = ClientChannel::Options());
//! Remove from channel cache
bool disconnect(const std::string& name,
const TestClientChannel::Options& conf = TestClientChannel::Options());
const ClientChannel::Options& conf = ClientChannel::Options());
//! Clear channel cache
void disconnect();
};
//! @}
}//namespace pvac
#endif // PVATESTCLIENT_H

View File

@ -20,21 +20,23 @@ namespace pva = epics::pvAccess;
typedef epicsGuard<epicsMutex> Guard;
TestTimeout::TestTimeout()
namespace pvac {
Timeout::Timeout()
:std::runtime_error("Timeout")
{}
struct TestClientChannel::Impl : public pva::ChannelRequester
struct ClientChannel::Impl : public pva::ChannelRequester
{
epicsMutex mutex;
pva::Channel::shared_pointer channel;
// assume few listeners per channel, store in vector
typedef std::vector<TestClientChannel::ConnectCallback*> listeners_t;
typedef std::vector<ClientChannel::ConnectCallback*> listeners_t;
listeners_t listeners;
virtual ~Impl() {}
virtual std::string getRequesterName() OVERRIDE FINAL { return "TestClientChannel::Impl"; }
virtual std::string getRequesterName() OVERRIDE FINAL { return "ClientChannel::Impl"; }
virtual void channelCreated(const pvd::Status& status, pva::Channel::shared_pointer const & channel) OVERRIDE FINAL {}
@ -45,7 +47,7 @@ struct TestClientChannel::Impl : public pva::ChannelRequester
Guard G(mutex);
notify = listeners;
}
TestConnectEvent evt;
ConnectEvent evt;
evt.connected = connectionState==pva::Channel::CONNECTED;
for(listeners_t::const_iterator it=notify.begin(), end=notify.end(); it!=end; ++it)
{
@ -66,33 +68,33 @@ struct TestClientChannel::Impl : public pva::ChannelRequester
}
};
TestClientChannel::Options::Options()
ClientChannel::Options::Options()
:priority(0)
,address()
{}
bool TestClientChannel::Options::operator<(const Options& O) const
bool ClientChannel::Options::operator<(const Options& O) const
{
return priority<O.priority || (priority==O.priority && address<O.address);
}
TestOperation::TestOperation(const std::tr1::shared_ptr<Impl>& i)
Operation::Operation(const std::tr1::shared_ptr<Impl>& i)
:impl(i)
{}
TestOperation::~TestOperation() {}
Operation::~Operation() {}
std::string TestOperation::name() const
std::string Operation::name() const
{
return impl ? impl->name() : "<NULL>";
}
void TestOperation::cancel()
void Operation::cancel()
{
if(impl) impl->cancel();
}
TestClientChannel::TestClientChannel(const std::tr1::shared_ptr<pva::ChannelProvider>& provider,
ClientChannel::ClientChannel(const std::tr1::shared_ptr<pva::ChannelProvider>& provider,
const std::string& name,
const Options& opt)
:impl(new Impl)
@ -104,17 +106,17 @@ TestClientChannel::TestClientChannel(const std::tr1::shared_ptr<pva::ChannelProv
throw std::logic_error("ChannelProvider failed to create Channel");
}
TestClientChannel::~TestClientChannel() {}
ClientChannel::~ClientChannel() {}
std::string TestClientChannel::name() const
std::string ClientChannel::name() const
{
return impl ? impl->channel->getChannelName() : "<NONE>";
}
void TestClientChannel::addConnectListener(ConnectCallback* cb)
void ClientChannel::addConnectListener(ConnectCallback* cb)
{
if(!impl) throw std::logic_error("Dead Channel");
TestConnectEvent evt;
ConnectEvent evt;
{
Guard G(impl->mutex);
@ -133,7 +135,7 @@ void TestClientChannel::addConnectListener(ConnectCallback* cb)
}
}
void TestClientChannel::removeConnectListener(ConnectCallback* cb)
void ClientChannel::removeConnectListener(ConnectCallback* cb)
{
if(!impl) throw std::logic_error("Dead Channel");
Guard G(impl->mutex);
@ -148,19 +150,19 @@ void TestClientChannel::removeConnectListener(ConnectCallback* cb)
}
std::tr1::shared_ptr<epics::pvAccess::Channel>
TestClientChannel::getChannel()
ClientChannel::getChannel()
{ return impl->channel; }
struct TestClientProvider::Impl
struct ClientProvider::Impl
{
pva::ChannelProvider::shared_pointer provider;
epicsMutex mutex;
typedef std::map<std::pair<std::string, TestClientChannel::Options>, std::tr1::weak_ptr<TestClientChannel::Impl> > channels_t;
typedef std::map<std::pair<std::string, ClientChannel::Options>, std::tr1::weak_ptr<ClientChannel::Impl> > channels_t;
channels_t channels;
};
TestClientProvider::TestClientProvider(const std::string& providerName,
ClientProvider::ClientProvider(const std::string& providerName,
const std::tr1::shared_ptr<epics::pvAccess::Configuration>& conf)
:impl(new Impl)
{
@ -172,31 +174,31 @@ TestClientProvider::TestClientProvider(const std::string& providerName,
THROW_EXCEPTION2(std::invalid_argument, providerName);
}
TestClientProvider::~TestClientProvider() {}
ClientProvider::~ClientProvider() {}
TestClientChannel
TestClientProvider::connect(const std::string& name,
const TestClientChannel::Options& conf)
ClientChannel
ClientProvider::connect(const std::string& name,
const ClientChannel::Options& conf)
{
Guard G(impl->mutex);
Impl::channels_t::key_type K(name, conf);
Impl::channels_t::iterator it(impl->channels.find(K));
if(it!=impl->channels.end()) {
// cache hit
std::tr1::shared_ptr<TestClientChannel::Impl> chan(it->second.lock());
std::tr1::shared_ptr<ClientChannel::Impl> chan(it->second.lock());
if(chan)
return TestClientChannel(chan);
return ClientChannel(chan);
else
impl->channels.erase(it); // remove stale
}
// cache miss
TestClientChannel ret(impl->provider, name, conf);
ClientChannel ret(impl->provider, name, conf);
impl->channels[K] = ret.impl;
return ret;
}
bool TestClientProvider::disconnect(const std::string& name,
const TestClientChannel::Options& conf)
bool ClientProvider::disconnect(const std::string& name,
const ClientChannel::Options& conf)
{
Guard G(impl->mutex);
@ -207,8 +209,10 @@ bool TestClientProvider::disconnect(const std::string& name,
return found;
}
void TestClientProvider::disconnect()
void ClientProvider::disconnect()
{
Guard G(impl->mutex);
impl->channels.clear();
}
} //namespace pvac

View File

@ -24,34 +24,34 @@ typedef epicsGuardRelease<epicsMutex> UnGuard;
namespace {
struct GetPutter : public pva::ChannelPutRequester,
public TestOperation::Impl
public pvac::Operation::Impl
{
mutable epicsMutex mutex;
bool started;
operation_type::shared_pointer op;
TestClientChannel::GetCallback *getcb;
TestClientChannel::PutCallback *putcb;
TestGetEvent event;
pvac::ClientChannel::GetCallback *getcb;
pvac::ClientChannel::PutCallback *putcb;
pvac::GetEvent event;
GetPutter(TestClientChannel::GetCallback* cb) :started(false), getcb(cb), putcb(0) {}
GetPutter(TestClientChannel::PutCallback* cb) :started(false), getcb(0), putcb(cb) {}
GetPutter(pvac::ClientChannel::GetCallback* cb) :started(false), getcb(cb), putcb(0) {}
GetPutter(pvac::ClientChannel::PutCallback* cb) :started(false), getcb(0), putcb(cb) {}
virtual ~GetPutter() {}
void callEvent(Guard& G, TestGetEvent::event_t evt = TestGetEvent::Fail)
void callEvent(Guard& G, pvac::GetEvent::event_t evt = pvac::GetEvent::Fail)
{
if(!putcb && !getcb) return;
event.event = evt;
if(putcb) {
TestClientChannel::PutCallback *cb=putcb;
pvac::ClientChannel::PutCallback *cb=putcb;
putcb = 0;
UnGuard U(G);
cb->putDone(event);
}
if(getcb) {
TestClientChannel::GetCallback *cb=getcb;
pvac::ClientChannel::GetCallback *cb=getcb;
getcb = 0;
UnGuard U(G);
cb->getDone(event);
@ -68,7 +68,7 @@ struct GetPutter : public pva::ChannelPutRequester,
{
Guard G(mutex);
if(started && op) op->cancel();
callEvent(G, TestGetEvent::Cancel);
callEvent(G, pvac::GetEvent::Cancel);
}
virtual std::string getRequesterName() OVERRIDE FINAL
@ -97,9 +97,9 @@ struct GetPutter : public pva::ChannelPutRequester,
started = true;
} else if(putcb){
TestClientChannel::PutCallback *cb(putcb);
pvac::ClientChannel::PutCallback *cb(putcb);
pvd::BitSet::shared_pointer tosend(new pvd::BitSet);
TestClientChannel::PutCallback::Args args(*tosend);
pvac::ClientChannel::PutCallback::Args args(*tosend);
try {
UnGuard U(G);
cb->putBuild(structure, args);
@ -145,7 +145,7 @@ struct GetPutter : public pva::ChannelPutRequester,
event.message.clear();
}
callEvent(G, status.isSuccess()? TestGetEvent::Success : TestGetEvent::Fail);
callEvent(G, status.isSuccess()? pvac::GetEvent::Success : pvac::GetEvent::Fail);
}
virtual void getDone(
@ -165,14 +165,16 @@ struct GetPutter : public pva::ChannelPutRequester,
event.value = pvStructure;
// assume bitSet->get(0)==true as we only make one request
callEvent(G, status.isSuccess()? TestGetEvent::Success : TestGetEvent::Fail);
callEvent(G, status.isSuccess()? pvac::GetEvent::Success : pvac::GetEvent::Fail);
}
};
} //namespace
TestOperation
TestClientChannel::get(TestClientChannel::GetCallback* cb,
namespace pvac {
Operation
ClientChannel::get(ClientChannel::GetCallback* cb,
epics::pvData::PVStructure::const_shared_pointer pvRequest)
{
if(!impl) throw std::logic_error("Dead Channel");
@ -186,11 +188,11 @@ TestClientChannel::get(TestClientChannel::GetCallback* cb,
ret->op = getChannel()->createChannelPut(ret, std::tr1::const_pointer_cast<pvd::PVStructure>(pvRequest));
}
return TestOperation(ret);
return Operation(ret);
}
TestOperation
TestClientChannel::put(PutCallback* cb,
Operation
ClientChannel::put(PutCallback* cb,
epics::pvData::PVStructure::const_shared_pointer pvRequest)
{
if(!impl) throw std::logic_error("Dead Channel");
@ -204,6 +206,8 @@ TestClientChannel::put(PutCallback* cb,
ret->op = getChannel()->createChannelPut(ret, std::tr1::const_pointer_cast<pvd::PVStructure>(pvRequest));
}
return TestOperation(ret);
return Operation(ret);
}
}//namespace pvac

View File

@ -20,19 +20,21 @@ namespace pva = epics::pvAccess;
typedef epicsGuard<epicsMutex> Guard;
typedef epicsGuardRelease<epicsMutex> UnGuard;
struct TestMonitor::Impl : public pva::MonitorRequester
namespace pvac {
struct Monitor::Impl : public pva::MonitorRequester
{
mutable epicsMutex mutex;
pva::Channel::shared_pointer chan;
operation_type::shared_pointer op;
bool started, done, seenEmpty;
TestClientChannel::MonitorCallback *cb;
TestMonitorEvent event;
ClientChannel::MonitorCallback *cb;
MonitorEvent event;
pva::MonitorElement::Ref last;
Impl(TestClientChannel::MonitorCallback* cb)
Impl(ClientChannel::MonitorCallback* cb)
:started(false)
,done(false)
,seenEmpty(false)
@ -40,14 +42,14 @@ struct TestMonitor::Impl : public pva::MonitorRequester
{}
virtual ~Impl() {}
void callEvent(Guard& G, TestMonitorEvent::event_t evt = TestMonitorEvent::Fail)
void callEvent(Guard& G, MonitorEvent::event_t evt = MonitorEvent::Fail)
{
TestClientChannel::MonitorCallback *cb=this->cb;
ClientChannel::MonitorCallback *cb=this->cb;
if(!cb) return;
event.event = evt;
if(evt==TestMonitorEvent::Fail || evt==TestMonitorEvent::Cancel)
if(evt==MonitorEvent::Fail || evt==MonitorEvent::Cancel)
this->cb = 0; // last event
try {
@ -55,10 +57,10 @@ struct TestMonitor::Impl : public pva::MonitorRequester
cb->monitorEvent(event);
return;
}catch(std::exception& e){
if(!this->cb || evt==TestMonitorEvent::Fail) {
LOG(pva::logLevelError, "Unhandled exception in TestClientChannel::MonitorCallback::monitorEvent(): %s", e.what());
if(!this->cb || evt==MonitorEvent::Fail) {
LOG(pva::logLevelError, "Unhandled exception in ClientChannel::MonitorCallback::monitorEvent(): %s", e.what());
} else {
event.event = TestMonitorEvent::Fail;
event.event = MonitorEvent::Fail;
event.message = e.what();
}
}
@ -68,7 +70,7 @@ struct TestMonitor::Impl : public pva::MonitorRequester
cb->monitorEvent(event);
return;
}catch(std::exception& e){
LOG(pva::logLevelError, "Unhandled exception following exception in TestClientChannel::MonitorCallback::monitorEvent(): %s", e.what());
LOG(pva::logLevelError, "Unhandled exception following exception in ClientChannel::MonitorCallback::monitorEvent(): %s", e.what());
}
}
@ -111,7 +113,7 @@ struct TestMonitor::Impl : public pva::MonitorRequester
if(!cb || done) return;
event.message = "Disconnect";
started = false;
callEvent(G, TestMonitorEvent::Disconnect);
callEvent(G, MonitorEvent::Disconnect);
}
virtual void monitorEvent(pva::MonitorPtr const & monitor) OVERRIDE FINAL
@ -120,7 +122,7 @@ struct TestMonitor::Impl : public pva::MonitorRequester
if(!cb || done) return;
event.message.clear();
callEvent(G, TestMonitorEvent::Data);
callEvent(G, MonitorEvent::Data);
}
virtual void unlisten(pva::MonitorPtr const & monitor) OVERRIDE FINAL
@ -130,24 +132,24 @@ struct TestMonitor::Impl : public pva::MonitorRequester
done = true;
if(seenEmpty)
callEvent(G, TestMonitorEvent::Data);
callEvent(G, MonitorEvent::Data);
// else // wait until final poll()
}
};
TestMonitor::TestMonitor(const std::tr1::shared_ptr<Impl>& impl)
Monitor::Monitor(const std::tr1::shared_ptr<Impl>& impl)
:impl(impl)
{}
TestMonitor::~TestMonitor() {}
Monitor::~Monitor() {}
std::string TestMonitor::name() const
std::string Monitor::name() const
{
return impl ? impl->chan->getChannelName() : "<NULL>";
}
void TestMonitor::cancel()
void Monitor::cancel()
{
if(!impl) return;
Guard G(impl->mutex);
@ -162,10 +164,10 @@ void TestMonitor::cancel()
impl->started = false;
}
impl->op->destroy();
impl->callEvent(G, TestMonitorEvent::Cancel);
impl->callEvent(G, MonitorEvent::Cancel);
}
bool TestMonitor::poll()
bool Monitor::poll()
{
if(!impl) return false;
Guard G(impl->mutex);
@ -183,22 +185,22 @@ bool TestMonitor::poll()
return impl->seenEmpty = !!root;
}
bool TestMonitor::complete() const
bool Monitor::complete() const
{
if(impl) return true;
Guard G(impl->mutex);
return impl->done && impl->seenEmpty;
}
TestMonitor
TestClientChannel::monitor(MonitorCallback *cb,
Monitor
ClientChannel::monitor(MonitorCallback *cb,
epics::pvData::PVStructure::const_shared_pointer pvRequest)
{
if(!impl) throw std::logic_error("Dead Channel");
if(!pvRequest)
pvRequest = pvd::createRequest("field()");
std::tr1::shared_ptr<TestMonitor::Impl> ret(new TestMonitor::Impl(cb));
std::tr1::shared_ptr<Monitor::Impl> ret(new Monitor::Impl(cb));
ret->chan = getChannel();
{
@ -206,5 +208,7 @@ TestClientChannel::monitor(MonitorCallback *cb,
ret->op = ret->chan->createMonitor(ret, std::tr1::const_pointer_cast<pvd::PVStructure>(pvRequest));
}
return TestMonitor(ret);
return Monitor(ret);
}
}//namespace pvac

View File

@ -22,25 +22,25 @@ typedef epicsGuardRelease<epicsMutex> UnGuard;
namespace {
struct RPCer : public pva::ChannelRPCRequester,
public TestOperation::Impl
public pvac::Operation::Impl
{
mutable epicsMutex mutex;
bool started;
operation_type::shared_pointer op;
TestClientChannel::GetCallback *cb;
TestGetEvent event;
pvac::ClientChannel::GetCallback *cb;
pvac::GetEvent event;
pvd::PVStructure::const_shared_pointer args;
RPCer(TestClientChannel::GetCallback* cb,
RPCer(pvac::ClientChannel::GetCallback* cb,
const pvd::PVStructure::const_shared_pointer& args) :started(false), cb(cb), args(args) {}
virtual ~RPCer() {}
void callEvent(Guard& G, TestGetEvent::event_t evt = TestGetEvent::Fail)
void callEvent(Guard& G, pvac::GetEvent::event_t evt = pvac::GetEvent::Fail)
{
TestClientChannel::GetCallback *cb=this->cb;
pvac::ClientChannel::GetCallback *cb=this->cb;
if(!cb) return;
event.event = evt;
@ -52,10 +52,10 @@ struct RPCer : public pva::ChannelRPCRequester,
cb->getDone(event);
return;
}catch(std::exception& e){
if(!this->cb || evt==TestGetEvent::Fail) {
LOG(pva::logLevelError, "Unhandled exception in TestClientChannel::GetCallback::getDone(): %s", e.what());
if(!this->cb || evt==pvac::GetEvent::Fail) {
LOG(pva::logLevelError, "Unhandled exception in ClientChannel::GetCallback::getDone(): %s", e.what());
} else {
event.event = TestGetEvent::Fail;
event.event = pvac::GetEvent::Fail;
event.message = e.what();
}
}
@ -65,7 +65,7 @@ struct RPCer : public pva::ChannelRPCRequester,
cb->getDone(event);
return;
}catch(std::exception& e){
LOG(pva::logLevelError, "Unhandled exception following exception in TestClientChannel::GetCallback::monitorEvent(): %s", e.what());
LOG(pva::logLevelError, "Unhandled exception following exception in ClientChannel::GetCallback::monitorEvent(): %s", e.what());
}
}
@ -79,7 +79,7 @@ struct RPCer : public pva::ChannelRPCRequester,
{
Guard G(mutex);
if(started && op) op->cancel();
callEvent(G, TestGetEvent::Cancel);
callEvent(G, pvac::GetEvent::Cancel);
}
virtual std::string getRequesterName() OVERRIDE FINAL
@ -129,14 +129,16 @@ struct RPCer : public pva::ChannelRPCRequester,
}
event.value = pvResponse;
callEvent(G, status.isSuccess()? TestGetEvent::Success : TestGetEvent::Fail);
callEvent(G, status.isSuccess()? pvac::GetEvent::Success : pvac::GetEvent::Fail);
}
};
}//namespace
TestOperation
TestClientChannel::rpc(GetCallback* cb,
namespace pvac {
Operation
ClientChannel::rpc(GetCallback* cb,
const epics::pvData::PVStructure::const_shared_pointer& arguments,
epics::pvData::PVStructure::const_shared_pointer pvRequest)
{
@ -151,5 +153,7 @@ TestClientChannel::rpc(GetCallback* cb,
ret->op = getChannel()->createChannelRPC(ret, std::tr1::const_pointer_cast<pvd::PVStructure>(pvRequest));
}
return TestOperation(ret);
return Operation(ret);
}
}//namespace pvac

View File

@ -22,16 +22,16 @@ typedef epicsGuard<epicsMutex> Guard;
typedef epicsGuardRelease<epicsMutex> UnGuard;
namespace {
struct GetWait : TestClientChannel::GetCallback
struct GetWait : pvac::ClientChannel::GetCallback
{
epicsMutex mutex;
epicsEvent event;
bool done;
TestGetEvent result;
pvac::GetEvent result;
GetWait() :done(false) {}
virtual ~GetWait() {}
virtual void getDone(const TestGetEvent& evt)
virtual void getDone(const pvac::GetEvent& evt)
{
{
Guard G(mutex);
@ -47,47 +47,51 @@ struct GetWait : TestClientChannel::GetCallback
};
} //namespace
namespace pvac {
pvd::PVStructure::const_shared_pointer
TestClientChannel::get(double timeout,
pvac::ClientChannel::get(double timeout,
pvd::PVStructure::const_shared_pointer pvRequest)
{
GetWait waiter;
TestOperation op(get(&waiter, pvRequest));
Operation op(get(&waiter, pvRequest));
{
Guard G(waiter.mutex);
while(!waiter.done) {
UnGuard U(G);
if(!waiter.event.wait(timeout)) {
op.cancel();
throw TestTimeout();
throw Timeout();
}
}
}
if(waiter.result.event==TestGetEvent::Success)
if(waiter.result.event==pvac::GetEvent::Success)
return waiter.result.value;
else
throw std::runtime_error(waiter.result.message);
}
pvd::PVStructure::const_shared_pointer
TestClientChannel::rpc(double timeout,
pvac::ClientChannel::rpc(double timeout,
const epics::pvData::PVStructure::const_shared_pointer& arguments,
epics::pvData::PVStructure::const_shared_pointer pvRequest)
{
GetWait waiter;
TestOperation op(rpc(&waiter, arguments, pvRequest));
Operation op(rpc(&waiter, arguments, pvRequest));
{
Guard G(waiter.mutex);
while(!waiter.done) {
UnGuard U(G);
if(!waiter.event.wait(timeout)) {
op.cancel();
throw TestTimeout();
throw Timeout();
}
}
}
if(waiter.result.event==TestGetEvent::Success)
if(waiter.result.event==pvac::GetEvent::Success)
return waiter.result.value;
else
throw std::runtime_error(waiter.result.message);
}
}//namespace pvac