This is Unofficial EPICS BASE Doxygen Site
server.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 <epicsMutex.h>
7 #include <epicsGuard.h>
8 
9 #include <pv/sharedPtr.h>
10 #include <pv/sharedVector.h>
11 #include <pv/pvData.h>
12 #include <pv/bitSet.h>
13 #include <pv/createRequest.h>
14 #include <pv/status.h>
15 #include <pv/reftrack.h>
16 
17 #define epicsExportSharedSymbols
18 #include "pva/server.h"
19 #include "pv/pvAccess.h"
20 #include "pv/security.h"
21 #include "pv/reftrack.h"
22 
23 namespace pvd = epics::pvData;
24 namespace pva = epics::pvAccess;
25 
28 
29 namespace pvas {
30 
32 {
34 
35  static size_t num_instances;
36 
37  const std::string name;
38  pva::ChannelFind::shared_pointer finder; // const after ctor
39  std::tr1::weak_ptr<Impl> internal_self, external_self; // const after ctor
40 
41  mutable epicsMutex mutex;
42 
43  typedef StaticProvider::builders_t builders_t;
44  builders_t builders;
45 
46  Impl(const std::string& name)
47  :name(name)
48  {
49  REFTRACE_INCREMENT(num_instances);
50  }
51  virtual ~Impl() {
52  REFTRACE_DECREMENT(num_instances);
53  }
54 
55  virtual void destroy() OVERRIDE FINAL {}
56 
57  virtual std::string getProviderName() OVERRIDE FINAL { return name; }
58  virtual pva::ChannelFind::shared_pointer channelFind(std::string const & name,
59  pva::ChannelFindRequester::shared_pointer const & requester) OVERRIDE FINAL
60  {
61  bool found;
62 
63  {
64  Guard G(mutex);
65 
66  found = builders.find(name)!=builders.end();
67  }
68  requester->channelFindResult(pvd::Status(), finder, found);
69  return finder;
70  }
71  virtual pva::ChannelFind::shared_pointer channelList(pva::ChannelListRequester::shared_pointer const & requester) OVERRIDE FINAL
72  {
74  {
75  Guard G(mutex);
76  names.reserve(builders.size());
77  for(builders_t::const_iterator it(builders.begin()), end(builders.end()); it!=end; ++it) {
78  names.push_back(it->first);
79  }
80  }
81  requester->channelListResult(pvd::Status(), finder, pvd::freeze(names), false);
82  return finder;
83  }
84  virtual pva::Channel::shared_pointer createChannel(std::string const & name,
85  pva::ChannelRequester::shared_pointer const & requester,
86  short priority, std::string const & address) OVERRIDE FINAL
87  {
88  pva::Channel::shared_pointer ret;
89  pvd::Status sts;
90 
91  builders_t::mapped_type builder;
92  {
93  Guard G(mutex);
94  builders_t::const_iterator it(builders.find(name));
95  if(it!=builders.end()) {
96  UnGuard U(G);
97  builder = it->second;
98  }
99  }
100  if(builder)
101  ret = builder->connect(Impl::shared_pointer(internal_self), name, requester);
102 
103  if(!ret) {
104  sts = pvd::Status::error("No such channel");
105  }
106 
107  requester->channelCreated(sts, ret);
108  return ret;
109  }
110 
111 };
112 
114 
116 
118  :impl(new Impl(name))
119 {
120  impl->internal_self = impl;
121  impl->finder = pva::ChannelFind::buildDummy(impl);
122  // wrap ref to call destroy when all external refs (from DyamicProvider::impl) are released.
123  impl.reset(impl.get(), pva::Destroyable::cleaner(impl));
124  impl->external_self = impl;
125 }
126 
128 
129 void StaticProvider::close(bool destroy)
130 {
131  Impl::builders_t pvs;
132  {
133  Guard G(impl->mutex);
134  if(destroy) {
135  pvs.swap(impl->builders); // consume
136  } else {
137  pvs = impl->builders; // just copy, close() is a relatively rare action
138  }
139  }
140  for(Impl::builders_t::iterator it(pvs.begin()), end(pvs.end()); it!=end; ++it) {
141  it->second->disconnect(destroy, impl.get());
142  }
143 }
144 
145 std::tr1::shared_ptr<epics::pvAccess::ChannelProvider> StaticProvider::provider() const
146 {
147  return Impl::shared_pointer(impl->internal_self);
148 }
149 
150 void StaticProvider::add(const std::string& name,
151  const std::tr1::shared_ptr<ChannelBuilder>& builder)
152 {
153  Guard G(impl->mutex);
154  if(impl->builders.find(name)!=impl->builders.end())
155  throw std::logic_error("Duplicate PV name");
156  impl->builders[name] = builder;
157 }
158 
159 std::tr1::shared_ptr<StaticProvider::ChannelBuilder> StaticProvider::remove(const std::string& name)
160 {
161  std::tr1::shared_ptr<StaticProvider::ChannelBuilder> ret;
162  {
163  Guard G(impl->mutex);
164  Impl::builders_t::iterator it(impl->builders.find(name));
165  if(it!=impl->builders.end()) {
166  ret = it->second;
167  impl->builders.erase(it);
168  }
169  }
170  if(ret)
171  ret->disconnect(true, impl.get());
172  return ret;
173 }
174 
175 StaticProvider::builders_t::const_iterator StaticProvider::begin() const {
176  Guard G(impl->mutex);
177  return impl->builders.begin();
178 }
179 
180 StaticProvider::builders_t::const_iterator StaticProvider::end() const {
181  Guard G(impl->mutex);
182  return impl->builders.end();
183 }
184 
185 
187 {
189 
190  static size_t num_instances;
191 
192  const std::string name;
193  const std::tr1::shared_ptr<Handler> handler;
194  pva::ChannelFind::shared_pointer finder; // const after ctor
195  std::tr1::weak_ptr<Impl> internal_self, external_self; // const after ctor
196 
197  mutable epicsMutex mutex;
198 
199  Impl(const std::string& name,
200  const std::tr1::shared_ptr<Handler>& handler)
201  :name(name)
202  ,handler(handler)
203  {
204  REFTRACE_INCREMENT(num_instances);
205  }
206  virtual ~Impl() {
207  REFTRACE_DECREMENT(num_instances);
208  }
209 
210  virtual void destroy() OVERRIDE FINAL {
211  handler->destroy();
212  }
213 
214  virtual std::string getProviderName() OVERRIDE FINAL { return name; }
215  virtual pva::ChannelFind::shared_pointer channelFind(std::string const & name,
216  pva::ChannelFindRequester::shared_pointer const & requester) OVERRIDE FINAL
217  {
218  bool found = false;
219  {
220  pva::PeerInfo::const_shared_pointer info(requester->getPeerInfo());
221  search_type search;
222  search.push_back(DynamicProvider::Search(name, info ? info.get() : 0));
223 
224  handler->hasChannels(search);
225 
226  found = !search.empty() && search[0].name()==name && search[0].claimed();
227  }
228  requester->channelFindResult(pvd::Status(), finder, found);
229  return finder;
230  }
231  virtual pva::ChannelFind::shared_pointer channelList(pva::ChannelListRequester::shared_pointer const & requester) OVERRIDE FINAL
232  {
234  bool dynamic = true;
235  handler->listChannels(names, dynamic);
236  requester->channelListResult(pvd::Status(), finder, pvd::freeze(names), dynamic);
237  return finder;
238  }
239  virtual pva::Channel::shared_pointer createChannel(std::string const & name,
240  pva::ChannelRequester::shared_pointer const & requester,
241  short priority, std::string const & address) OVERRIDE FINAL
242  {
243  pva::Channel::shared_pointer ret;
244  pvd::Status sts;
245 
246  ret = handler->createChannel(ChannelProvider::shared_pointer(internal_self), name, requester);
247  if(!ret)
248  sts = pvd::Status::error("Channel no longer available"); // because we only get here if channelFind() succeeds
249 
250  requester->channelCreated(sts, ret);
251  return ret;
252  }
253 
254 };
255 
257 
258 DynamicProvider::DynamicProvider(const std::string &name,
259  const std::tr1::shared_ptr<Handler> &handler)
260  :impl(new Impl(name, handler))
261 {
262  impl->internal_self = impl;
263  impl->finder = pva::ChannelFind::buildDummy(impl);
264  // wrap ref to call destroy when all external refs (from DyamicProvider::impl) are released.
265  impl.reset(impl.get(), pva::Destroyable::cleaner(impl));
266  impl->external_self = impl;
267 }
268 
270 
271 DynamicProvider::Handler::shared_pointer DynamicProvider::getHandler() const
272 {
273  return impl->handler;
274 }
275 
276 std::tr1::shared_ptr<epics::pvAccess::ChannelProvider> DynamicProvider::provider() const
277 {
278  return Impl::shared_pointer(impl->internal_self);
279 }
280 
282 {
283  epics::registerRefCounter("pvas::StaticProvider", &StaticProvider::Impl::num_instances);
284  epics::registerRefCounter("pvas::DynamicProvider", &DynamicProvider::Impl::num_instances);
285 }
286 
287 } // namespace pvas
std::tr1::weak_ptr< Impl > internal_self
Definition: server.cpp:39
A single client serach request. May be associated with more than one name.
Definition: server.h:171
virtual pva::ChannelFind::shared_pointer channelFind(std::string const &name, pva::ChannelFindRequester::shared_pointer const &requester) OVERRIDE FINAL
Definition: server.cpp:215
virtual std::string getProviderName() OVERRIDE FINAL
Definition: server.cpp:57
virtual pva::ChannelFind::shared_pointer channelList(pva::ChannelListRequester::shared_pointer const &requester) OVERRIDE FINAL
Definition: server.cpp:231
A holder for a contiguous piece of memory.
Definition: sharedVector.h:27
epicsGuard< epicsMutex > Guard
Definition: server.cpp:26
static Status error(const std::string &m)
Definition: status.h:50
Impl(const std::string &name)
Definition: server.cpp:46
std::vector< Search > search_type
Definition: server.h:191
virtual pva::ChannelFind::shared_pointer channelList(pva::ChannelListRequester::shared_pointer const &requester) OVERRIDE FINAL
Definition: server.cpp:71
POINTER_DEFINITIONS(StaticProvider)
static size_t num_instances
Definition: server.cpp:190
void close(bool destroy=false)
Definition: server.cpp:129
std::tr1::shared_ptr< epics::pvAccess::ChannelProvider > provider() const
Fetch the underlying ChannelProvider. Usually to build a ServerContext around.
Definition: server.cpp:276
pva::ChannelFind::shared_pointer finder
Definition: server.cpp:194
StaticProvider::builders_t builders_t
Definition: server.cpp:43
std::tr1::weak_ptr< Impl > external_self
Definition: server.cpp:39
const_iterator end() const
Definition: server.cpp:180
virtual std::string getProviderName() OVERRIDE FINAL
Definition: server.cpp:214
#define OVERRIDE
Definition: pvAccess.h:55
std::tr1::shared_ptr< epics::pvAccess::ChannelProvider > provider() const
Fetch the underlying ChannelProvider. Usually to build a ServerContext around.
Definition: server.cpp:145
const std::string name
Definition: server.cpp:192
virtual void destroy() OVERRIDE FINAL
Definition: server.cpp:210
Holds all PVA related.
Definition: pvif.h:34
virtual void destroy() OVERRIDE FINAL
Definition: server.cpp:55
pvData
Definition: monitor.h:428
std::tr1::shared_ptr< ChannelBuilder > remove(const std::string &name)
Definition: server.cpp:159
const std::tr1::shared_ptr< Handler > handler
Definition: server.cpp:193
void push_back(param_type v)
Definition: sharedVector.h:602
APIs for the epicsMutex mutual exclusion semaphore.
epicsGuardRelease< epicsMutex > UnGuard
Definition: server.cpp:27
DynamicProvider(const std::string &name, const std::tr1::shared_ptr< Handler > &handler)
Definition: server.cpp:258
StaticProvider(const std::string &name)
Definition: server.cpp:117
Impl(const std::string &name, const std::tr1::shared_ptr< Handler > &handler)
Definition: server.cpp:199
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
pva::ChannelFind::shared_pointer finder
Definition: server.cpp:38
static size_t num_instances
Definition: server.cpp:35
static ChannelFind::shared_pointer buildDummy(const std::tr1::shared_ptr< ChannelProvider > &provider)
Definition: pvAccess.cpp:473
See Server API API.
void registerRefCounter(const char *name, const size_t *counter)
Definition: reftrack.cpp:59
void registerRefTrackServer()
Definition: server.cpp:281
const std::string name
Definition: server.cpp:37
void add(const std::string &name, const std::tr1::shared_ptr< ChannelBuilder > &builder)
Add a PV (eg. SharedPV) to this provider.
Definition: server.cpp:150
virtual pva::Channel::shared_pointer createChannel(std::string const &name, pva::ChannelRequester::shared_pointer const &requester, short priority, std::string const &address) OVERRIDE FINAL
Definition: server.cpp:239
virtual pva::ChannelFind::shared_pointer channelFind(std::string const &name, pva::ChannelFindRequester::shared_pointer const &requester) OVERRIDE FINAL
Definition: server.cpp:58
Handler::shared_pointer getHandler() const
Definition: server.cpp:271
virtual pva::Channel::shared_pointer createChannel(std::string const &name, pva::ChannelRequester::shared_pointer const &requester, short priority, std::string const &address) OVERRIDE FINAL
Definition: server.cpp:84
const_iterator begin() const
Definition: server.cpp:175
void reserve(size_t i)
Set array capacity.
Definition: sharedVector.h:428
#define FINAL
Definition: pvAccess.h:48
std::tr1::weak_ptr< Impl > internal_self
Definition: server.cpp:195