Add SharedPV

This commit is contained in:
Michael Davidsaver
2018-05-29 21:35:34 -07:00
parent 146fbbc719
commit 74c2ec1ec3
14 changed files with 2050 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
#include <list>
#include <epicsMutex.h>
#include <epicsGuard.h>
#include <shareLib.h>
#include <pv/sharedPtr.h>
#include <pv/noDefaultMethods.h>
#define epicsExportSharedSymbols
#include "sharedstateimpl.h"
namespace {
struct RPCOP : public pvas::Operation::Impl
{
const std::tr1::shared_ptr<pvas::SharedRPC> op;
RPCOP(const std::tr1::shared_ptr<pvas::SharedRPC>& op,
const pvd::PVStructure::const_shared_pointer& pvRequest,
const pvd::PVStructure::const_shared_pointer& value)
:Impl(pvRequest, value, pvd::BitSet().set(0))
,op(op)
{}
virtual ~RPCOP() {}
virtual pva::Channel::shared_pointer getChannel() OVERRIDE FINAL
{
return op->channel;
}
virtual pva::ChannelBaseRequester::shared_pointer getRequester() OVERRIDE FINAL
{
return op->requester.lock();
}
virtual void complete(const pvd::Status& sts,
const epics::pvData::PVStructure* value) OVERRIDE FINAL
{
{
Guard G(mutex);
if(done)
throw std::logic_error("Operation already complete");
done = true;
}
epics::pvData::PVStructurePtr tosend;
if(!sts.isSuccess()) {
// no data for error
} else if(value) {
tosend = pvd::getPVDataCreate()->createPVStructure(value->getStructure());
tosend->copyUnchecked(*value);
} else {
// RPC with null result. Make empty structure
tosend = pvd::getPVDataCreate()->createPVStructure(
pvd::getFieldCreate()
->createFieldBuilder()
->createStructure());
}
pva::ChannelRPCRequester::shared_pointer req(op->requester.lock());
if(req)
req->requestDone(sts, op, tosend);
}
};
}
namespace pvas {
size_t SharedRPC::num_instances;
SharedRPC::SharedRPC(const std::tr1::shared_ptr<SharedChannel>& channel,
const requester_type::shared_pointer& requester,
const pvd::PVStructure::const_shared_pointer &pvRequest)
:channel(channel)
,requester(requester)
,pvRequest(pvRequest)
{
REFTRACE_INCREMENT(num_instances);
}
SharedRPC::~SharedRPC() {
Guard G(channel->owner->mutex);
channel->owner->rpcs.remove(this);
REFTRACE_DECREMENT(num_instances);
}
void SharedRPC::destroy() {}
std::tr1::shared_ptr<pva::Channel> SharedRPC::getChannel()
{
return channel;
}
void SharedRPC::cancel() {}
void SharedRPC::lastRequest() {}
void SharedRPC::request(epics::pvData::PVStructure::shared_pointer const & pvArgument)
{
std::tr1::shared_ptr<SharedPV::Handler> handler;
{
Guard G(channel->owner->mutex);
handler = channel->owner->handler;
}
std::tr1::shared_ptr<RPCOP> impl(new RPCOP(shared_from_this(), pvRequest, pvArgument),
Operation::Impl::Cleanup());
if(handler) {
Operation op(impl);
handler->onRPC(channel->owner, op);
}
}
} // namespace pvas