This is Unofficial EPICS BASE Doxygen Site
sharedstate_put.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 #include <pv/createRequest.h>
22 
23 #define epicsExportSharedSymbols
24 #include "sharedstateimpl.h"
25 
26 namespace {
27 struct PutOP : public pvas::Operation::Impl
28 {
29  const std::tr1::shared_ptr<pvas::detail::SharedPut> op;
30 
31  PutOP(const std::tr1::shared_ptr<pvas::detail::SharedPut>& op,
32  const pvd::PVStructure::const_shared_pointer& pvRequest,
33  const pvd::PVStructure::const_shared_pointer& value,
34  const pvd::BitSet& changed)
35  :Impl(pvRequest, value, changed)
36  ,op(op)
37  {
38  pva::ChannelRequester::shared_pointer req(op->channel->getChannelRequester());
39  if(req)
40  info = req->getPeerInfo();
41  }
42  virtual ~PutOP() {}
43 
44  virtual pva::Channel::shared_pointer getChannel() OVERRIDE FINAL
45  {
46  return op->channel;
47  }
48 
49  virtual pva::ChannelBaseRequester::shared_pointer getRequester() OVERRIDE FINAL
50  {
51  return op->requester.lock();
52  }
53 
54  virtual void complete(const pvd::Status& sts,
56  {
57  if(value)
58  throw std::logic_error("Put can't complete() with data");
59 
60  {
61  Guard G(mutex);
62  if(done)
63  throw std::logic_error("Operation already complete");
64  done = true;
65  }
66 
67  pva::ChannelPutRequester::shared_pointer req(op->requester.lock());
68  if(req)
69  req->putDone(sts, op);
70  }
71 };
72 }
73 
74 
75 namespace pvas {
76 namespace detail {
77 
78 size_t SharedPut::num_instances;
79 
80 SharedPut::SharedPut(const std::tr1::shared_ptr<SharedChannel>& channel,
81  const requester_type::shared_pointer& requester,
82  const pvd::PVStructure::const_shared_pointer &pvRequest)
83  :channel(channel)
84  ,requester(requester)
85  ,pvRequest(pvRequest)
86 {
87  REFTRACE_INCREMENT(num_instances);
88 }
89 
91 {
92  Guard G(channel->owner->mutex);
93  channel->owner->puts.remove(this);
94  REFTRACE_DECREMENT(num_instances);
95 }
96 
98 
99 std::tr1::shared_ptr<pva::Channel> SharedPut::getChannel()
100 {
101  return channel;
102 }
103 
105 
107 
109  pvd::PVStructure::shared_pointer const & pvPutStructure,
110  pvd::BitSet::shared_pointer const & putBitSet)
111 {
112  std::tr1::shared_ptr<SharedPV::Handler> handler;
113  pvd::PVStructure::shared_pointer realval;
114  pvd::BitSet changed;
115  pvd::Status sts;
116  {
117  Guard G(channel->owner->mutex);
118 
119  if(channel->dead) {
120  sts = pvd::Status::error("Dead Channel");
121 
122  } else if(pvPutStructure->getStructure()!=mapper.requested()) {
123  requester_type::shared_pointer req(requester.lock());
124  sts = pvd::Status::error("Type changed");
125 
126  } else {
127 
128  handler = channel->owner->handler;
129 
130  realval = mapper.buildBase();
131 
132  mapper.copyBaseFromRequested(*realval, changed, *pvPutStructure, *putBitSet);
133  }
134  }
135 
136  if(!sts.isOK()) {
137  requester_type::shared_pointer req(requester.lock());
138  if(req)
139  req->putDone(sts, pva::ChannelPut::shared_pointer());
140 
141  } else {
142  std::tr1::shared_ptr<PutOP> impl(new PutOP(shared_from_this(), pvRequest, realval, changed),
144 
145  if(handler) {
146  Operation op(impl);
147  handler->onPut(channel->owner, op);
148  }
149  }
150 }
151 
153 {
154  pvd::Status sts;
155  pvd::PVStructurePtr current;
156  pvd::BitSetPtr changed;
157  {
158  Guard G(channel->owner->mutex);
159 
160  if(channel->dead) {
161  sts = pvd::Status::error("Dead Channel");
162 
163  } else if(channel->owner->current) {
164  assert(!!mapper.requested());
165 
166  current = mapper.buildRequested();
167  changed.reset(new pvd::BitSet);
168 
169  mapper.copyBaseToRequested(*channel->owner->current, channel->owner->valid,
170  *current, *changed);
171  }
172  }
173 
174  requester_type::shared_pointer req(requester.lock());
175  if(!req) return;
176 
177  if(!sts.isOK()) {
178  // no-op
179  } else if(!current) {
180  sts = pvd::Status::error("Get not possible, cache disabled");
181  }
182 
183  req->getDone(sts, shared_from_this(), current, changed);
184 }
185 
186 }} // namespace pvas::detail
virtual pva::Channel::shared_pointer getChannel()=0
void copyBaseToRequested(const PVStructure &base, const BitSet &baseMask, PVStructure &request, BitSet &requestMask) const
Definition: link.h:174
virtual void lastRequest() OVERRIDE FINAL
virtual void destroy() OVERRIDE FINAL
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
static Status error(const std::string &m)
Definition: status.h:50
const requester_type::weak_pointer requester
pvd::PVRequestMapper mapper
PVStructurePtr buildRequested() const
static size_t num_instances
A vector of bits.
Definition: bitSet.h:56
Mark external symbols and entry points for shared libraries.
#define OVERRIDE
Definition: pvAccess.h:55
virtual void put(epics::pvData::PVStructure::shared_pointer const &pvPutStructure, epics::pvData::BitSet::shared_pointer const &putBitSet) OVERRIDE FINAL
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
virtual pva::ChannelBaseRequester::shared_pointer getRequester()=0
const pvd::PVStructure::const_shared_pointer pvRequest
virtual void complete(const pvd::Status &sts, const epics::pvData::PVStructure *value)=0
See Server API API.
Data interface for a structure,.
Definition: pvData.h:712
const std::tr1::shared_ptr< SharedChannel > channel
std::tr1::shared_ptr< PVStructure > PVStructurePtr
Definition: pvData.h:87
virtual std::tr1::shared_ptr< pva::Channel > getChannel() OVERRIDE FINAL
void done(int k)
Definition: antelope.c:77
virtual void cancel() OVERRIDE FINAL
PVStructurePtr buildBase() const
std::tr1::shared_ptr< BitSet > BitSetPtr
Definition: bitSet.h:26
bool isOK() const
Definition: status.h:95
virtual void get() OVERRIDE FINAL
ChannelPut::shared_pointer op
Definition: pvAccess.cpp:132
const StructureConstPtr & requested() const
void copyBaseFromRequested(PVStructure &base, BitSet &baseMask, const PVStructure &request, const BitSet &requestMask) const
#define FINAL
Definition: pvAccess.h:48