22 #define epicsExportSharedSymbols 28 virtual ~MailboxHandler() {}
34 static std::tr1::shared_ptr<pvas::SharedPV::Handler>
build() {
35 std::tr1::shared_ptr<MailboxHandler> ret(
new MailboxHandler);
43 SharedPV::Handler::~Handler() {}
45 void SharedPV::Handler::onPut(
const SharedPV::shared_pointer&
pv,
Operation&
op)
50 void SharedPV::Handler::onRPC(
const SharedPV::shared_pointer&
pv,
Operation&
op)
55 SharedPV::Config::Config()
56 :dropEmptyUpdates(
true)
57 ,mapperMode(
pvd::PVRequestMapper::Mask)
60 size_t SharedPV::num_instances;
65 SharedPV::shared_pointer ret(
new SharedPV(handler, conf));
66 ret->internal_self = ret;
72 SharedPV::shared_pointer ret(
new SharedPV(std::tr1::shared_ptr<Handler>(), conf));
73 ret->internal_self = ret;
79 std::tr1::shared_ptr<Handler> handler(
new MailboxHandler);
80 SharedPV::shared_pointer ret(
new SharedPV(handler, conf));
81 ret->internal_self = ret;
86 :config(conf ? *conf :
Config())
91 REFTRACE_INCREMENT(num_instances);
96 REFTRACE_DECREMENT(num_instances);
102 this->handler = handler;
120 std::tr1::shared_ptr<detail::SharedPut>
put;
124 :put(put), type(type), status(status)
126 PutInfo(
const std::tr1::shared_ptr<detail::SharedPut>& put,
const pvd::StructureConstPtr& type,
const std::string& message)
127 :
put(put), type(type)
137 typedef std::vector<PutInfo> xputs_t;
138 typedef std::vector<std::tr1::shared_ptr<detail::SharedRPC> > xrpcs_t;
139 typedef std::vector<std::tr1::shared_ptr<pva::MonitorFIFO> > xmonitors_t;
140 typedef std::vector<std::tr1::shared_ptr<pva::GetFieldRequester> > xgetfields_t;
144 newvalue->copyUnchecked(value, valid);
148 xmonitors_t p_monitor;
149 xgetfields_t p_getfield;
154 throw std::logic_error(
"Already open()");
156 p_put.reserve(
puts.size());
157 p_rpc.reserve(rpcs.size());
158 p_monitor.reserve(monitors.size());
159 p_getfield.reserve(getfields.size());
166 if((*it)->channel->dead)
continue;
169 (*it)->mapper.compute(*current, *(*it)->pvRequest, config.mapperMode);
170 p_put.push_back(PutInfo((*it)->shared_from_this(), (*it)->mapper.requested(), (*it)->mapper.warnings()));
171 }
catch(std::runtime_error& e) {
175 }
catch(std::tr1::bad_weak_ptr&) {
179 FOR_EACH(rpcs_t::const_iterator, it, end, rpcs) {
180 if((*it)->connected || (*it)->channel->dead)
continue;
182 p_rpc.push_back((*it)->shared_from_this());
183 }
catch(std::tr1::bad_weak_ptr&) {}
185 FOR_EACH(monitors_t::const_iterator, it, end, monitors) {
186 if((*it)->channel->dead)
continue;
188 (*it)->open(newtype);
190 (*it)->post(*current, valid);
191 p_monitor.push_back((*it)->shared_from_this());
192 }
catch(std::tr1::bad_weak_ptr&) {}
195 FOR_EACH(getfields_t::iterator, it, end, getfields) {
197 p_getfield.push_back(it->lock());
202 FOR_EACH(xputs_t::iterator, it, end, p_put) {
203 detail::SharedPut::requester_type::shared_pointer
requester(it->put->requester.lock());
207 requester->channelPutConnect(it->status, it->put, it->type);
210 FOR_EACH(xrpcs_t::iterator, it, end, p_rpc) {
211 detail::SharedRPC::requester_type::shared_pointer
requester((*it)->requester.lock());
214 FOR_EACH(xmonitors_t::iterator, it, end, p_monitor) {
217 FOR_EACH(xgetfields_t::iterator, it, end, p_getfield) {
236 typedef std::vector<std::tr1::shared_ptr<pva::ChannelPutRequester> > xputs_t;
237 typedef std::vector<std::tr1::shared_ptr<pva::ChannelRPCRequester> > xrpcs_t;
238 typedef std::vector<std::tr1::shared_ptr<pva::MonitorFIFO> > xmonitors_t;
239 typedef std::vector<std::tr1::shared_ptr<detail::SharedChannel> > xchannels_t;
243 xmonitors_t p_monitor;
244 xchannels_t p_channel;
245 Handler::shared_pointer p_handler;
249 FOR_EACH(rpcs_t::const_iterator, it, end, rpcs) {
250 if(!(*it)->connected)
continue;
251 p_rpc.push_back((*it)->requester.lock());
256 p_put.reserve(
puts.size());
257 p_rpc.reserve(rpcs.size());
258 p_monitor.reserve(monitors.size());
259 p_channel.reserve(channels.size());
262 if(provider && (*it)->channel->provider.lock().get()!=provider)
264 (*it)->mapper.reset();
265 p_put.push_back((*it)->requester.lock());
267 FOR_EACH(monitors_t::const_iterator, it, end, monitors) {
270 p_monitor.push_back((*it)->shared_from_this());
271 }
catch(std::tr1::bad_weak_ptr&) { }
273 FOR_EACH(channels_t::const_iterator, it, end, channels) {
275 p_channel.push_back((*it)->shared_from_this());
276 }
catch(std::tr1::bad_weak_ptr&) { }
291 if(!channels.empty() && notifiedConn) {
293 notifiedConn =
false;
298 FOR_EACH(xputs_t::iterator, it, end, p_put) {
299 if(*it) (*it)->channelDisconnect(destroy);
301 FOR_EACH(xrpcs_t::iterator, it, end, p_rpc) {
302 if(*it) (*it)->channelDisconnect(destroy);
304 FOR_EACH(xmonitors_t::iterator, it, end, p_monitor) {
307 FOR_EACH(xchannels_t::iterator, it, end, p_channel) {
308 pva::ChannelRequester::shared_pointer req((*it)->requester.lock());
313 shared_pointer
self(internal_self);
314 p_handler->onLastDisconnect(
self);
322 throw std::logic_error(
"Can't build() before open()");
329 typedef std::vector<std::tr1::shared_ptr<pva::MonitorFIFO> > xmonitors_t;
330 xmonitors_t p_monitor;
335 throw std::logic_error(
"Not open()");
337 throw std::logic_error(
"Type mis-match");
340 current->copyUnchecked(value, changed);
344 p_monitor.reserve(monitors.size());
346 FOR_EACH(monitors_t::const_iterator, it, end, monitors) {
347 (*it)->post(value, changed);
348 p_monitor.push_back((*it)->shared_from_this());
351 FOR_EACH(xmonitors_t::iterator, it, end, p_monitor) {
360 throw std::logic_error(
"Not open()");
362 throw std::logic_error(
"Types do not match");
364 value.
copy(*current);
369 std::tr1::shared_ptr<pva::Channel>
371 const std::string &channelName,
372 const std::tr1::shared_ptr<pva::ChannelRequester>&
requester)
374 shared_pointer
self(internal_self);
375 std::tr1::shared_ptr<detail::SharedChannel> ret(
new detail::SharedChannel(
self, provider, channelName, requester));
382 realClose(destroy,
false, provider);
bool isOpen() const
test open-ness. cf. open() and close()
static Status warn(const std::string &m)
#define assert(exp)
Declare that a condition should be true.
std::tr1::shared_ptr< detail::SharedPut > put
static Status error(const std::string &m)
pvd::StructureConstPtr type
static shared_pointer buildMailbox(Config *conf=0)
A SharedPV which accepts all Put operations, and fails all RPC operations. In closed state...
void fetch(epics::pvData::PVStructure &value, epics::pvData::BitSet &valid)
Update arguments with current value, which is the initial value from open() with accumulated post() c...
std::tr1::shared_ptr< const Structure > StructureConstPtr
Mark external symbols and entry points for shared libraries.
virtual std::tr1::shared_ptr< epics::pvAccess::Channel > connect(const std::tr1::shared_ptr< epics::pvAccess::ChannelProvider > &provider, const std::string &channelName, const std::tr1::shared_ptr< epics::pvAccess::ChannelRequester > &requester) OVERRIDE FINAL
#define FOR_EACH(TYPE, IT, END, OBJ)
void setHandler(const std::tr1::shared_ptr< Handler > &handler)
Replace Handler given with ctor.
void copy(const PVStructure &from)
void open(const epics::pvData::PVStructure &value)
Shorthand for.
APIs for the epicsMutex mutual exclusion semaphore.
const ChannelProcessRequester::weak_pointer requester
Data interface for a structure,.
virtual void onPut(const SharedPV::shared_pointer &pv, Operation &op)
Client requests Put.
std::tr1::shared_ptr< epics::pvData::PVStructure > build()
std::tr1::shared_ptr< PVStructure > PVStructurePtr
const epics::pvData::BitSet & changed() const
Applies to value(). Which fields of input data are actual valid. Others should not be used...
void close(bool destroy=false)
Handler::shared_pointer getHandler() const
const StructureConstPtr & getStructure() const
ChannelPut::shared_pointer op
void post(const epics::pvData::PVStructure &value, const epics::pvData::BitSet &changed)
virtual void disconnect(bool destroy, const epics::pvAccess::ChannelProvider *provider) OVERRIDE FINAL
FORCE_INLINE const PVDataCreatePtr & getPVDataCreate()
const epics::pvData::PVStructure & value() const
static shared_pointer buildReadOnly(Config *conf=0)
A SharedPV which fails all Put and RPC operations. In closed state.