This is Unofficial EPICS BASE Doxygen Site
sharedstate_rpc.cpp
Go to the documentation of this file.
1 /*
2  * Copyright information and license terms for this software can be
3  * found in the file LICENSE that is included with the distribution
4  */
5 
6 #include <list>
7 
8 #include <epicsMutex.h>
9 #include <epicsGuard.h>
10 #include <errlog.h>
11 
12 #include <shareLib.h>
13 #include <pv/sharedPtr.h>
14 #include <pv/noDefaultMethods.h>
15 #include <pv/sharedVector.h>
16 #include <pv/bitSet.h>
17 #include <pv/pvData.h>
18 #include <pv/createRequest.h>
19 #include <pv/status.h>
20 #include <pv/reftrack.h>
21 
22 #define epicsExportSharedSymbols
23 #include "sharedstateimpl.h"
24 
25 namespace {
26 struct RPCOP : public pvas::Operation::Impl
27 {
28  const std::tr1::shared_ptr<pvas::detail::SharedRPC> op;
29 
30  RPCOP(const std::tr1::shared_ptr<pvas::detail::SharedRPC>& op,
31  const pvd::PVStructure::const_shared_pointer& pvRequest,
32  const pvd::PVStructure::const_shared_pointer& value)
33  :Impl(pvRequest, value, pvd::BitSet().set(0))
34  ,op(op)
35  {
36  pva::ChannelRequester::shared_pointer req(op->channel->getChannelRequester());
37  if(req)
38  info = req->getPeerInfo();
39  }
40  virtual ~RPCOP() {}
41 
42  virtual pva::Channel::shared_pointer getChannel() OVERRIDE FINAL
43  {
44  return op->channel;
45  }
46 
47  virtual pva::ChannelBaseRequester::shared_pointer getRequester() OVERRIDE FINAL
48  {
49  return op->requester.lock();
50  }
51 
52  virtual void complete(const pvd::Status& sts,
54  {
55  {
56  Guard G(mutex);
57  if(done)
58  throw std::logic_error("Operation already complete");
59  done = true;
60  }
62  if(!sts.isSuccess()) {
63  // no data for error
64  } else if(value) {
65  tosend = pvd::getPVDataCreate()->createPVStructure(value->getStructure());
66  tosend->copyUnchecked(*value);
67  } else {
68  // RPC with null result. Make empty structure
69  tosend = pvd::getPVDataCreate()->createPVStructure(
71  ->createFieldBuilder()
72  ->createStructure());
73  }
74  pva::ChannelRPCRequester::shared_pointer req(op->requester.lock());
75  if(req)
76  req->requestDone(sts, op, tosend);
77  }
78 };
79 }
80 
81 namespace pvas {
82 namespace detail {
83 
84 size_t SharedRPC::num_instances;
85 
86 SharedRPC::SharedRPC(const std::tr1::shared_ptr<SharedChannel>& channel,
87  const requester_type::shared_pointer& requester,
88  const pvd::PVStructure::const_shared_pointer &pvRequest)
89  :channel(channel)
90  ,requester(requester)
91  ,pvRequest(pvRequest)
92  ,connected(false)
93 {
94  REFTRACE_INCREMENT(num_instances);
95 }
96 
98  Guard G(channel->owner->mutex);
99  channel->owner->rpcs.remove(this);
100  REFTRACE_DECREMENT(num_instances);
101 }
102 
104 
105 std::tr1::shared_ptr<pva::Channel> SharedRPC::getChannel()
106 {
107  return channel;
108 }
109 
111 
113 
114 void SharedRPC::request(epics::pvData::PVStructure::shared_pointer const & pvArgument)
115 {
116  std::tr1::shared_ptr<SharedPV::Handler> handler;
117  pvd::Status sts;
118  {
119  Guard G(channel->owner->mutex);
120  if(channel->dead) {
121  sts = pvd::Status::error("Dead Channel");
122 
123  } else {
124  handler = channel->owner->handler;
125  }
126  }
127 
128  if(!sts.isOK()) {
129  requester_type::shared_pointer req(requester.lock());
130  if(req)
131  req->requestDone(sts, shared_from_this(), pvd::PVStructurePtr());
132 
133  } else {
134  std::tr1::shared_ptr<RPCOP> impl(new RPCOP(shared_from_this(), pvRequest, pvArgument),
136 
137  if(handler) {
138  Operation op(impl);
139  handler->onRPC(channel->owner, op);
140  }
141  }
142 }
143 
144 
145 }} // namespace pvas::detail
virtual pva::Channel::shared_pointer getChannel()=0
Definition: link.h:174
static Status error(const std::string &m)
Definition: status.h:50
A vector of bits.
Definition: bitSet.h:56
Mark external symbols and entry points for shared libraries.
const pvd::PVStructure::const_shared_pointer pvRequest
#define OVERRIDE
Definition: pvAccess.h:55
const std::tr1::shared_ptr< SharedChannel > channel
epicsMutex mutex
Definition: pvAccess.cpp:71
APIs for the epicsMutex mutual exclusion semaphore.
Impl(const pvd::PVStructure::const_shared_pointer &pvRequest, const pvd::PVStructure::const_shared_pointer &value, const pvd::BitSet &changed, int debugLvl=0)
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
bool isSuccess() const
Definition: status.h:103
virtual pva::ChannelBaseRequester::shared_pointer getRequester()=0
virtual void complete(const pvd::Status &sts, const epics::pvData::PVStructure *value)=0
virtual void cancel() OVERRIDE FINAL
See Server API API.
Data interface for a structure,.
Definition: pvData.h:712
virtual std::tr1::shared_ptr< pva::Channel > getChannel() OVERRIDE FINAL
FORCE_INLINE const FieldCreatePtr & getFieldCreate()
std::tr1::shared_ptr< PVStructure > PVStructurePtr
Definition: pvData.h:87
virtual void destroy() OVERRIDE FINAL
void done(int k)
Definition: antelope.c:77
bool isOK() const
Definition: status.h:95
const StructureConstPtr & getStructure() const
Definition: pvData.h:731
ChannelPut::shared_pointer op
Definition: pvAccess.cpp:132
virtual void request(epics::pvData::PVStructure::shared_pointer const &pvArgument) OVERRIDE FINAL
const requester_type::weak_pointer requester
#define false
Definition: flexdef.h:85
FORCE_INLINE const PVDataCreatePtr & getPVDataCreate()
Definition: pvData.h:1648
virtual void lastRequest() OVERRIDE FINAL
#define FINAL
Definition: pvAccess.h:48