33 void pdb_single_event(
void *user_arg,
struct dbChannel *chan,
34 int eventsRemaining,
struct db_field_log *pfl)
44 self->scratch.clear();
48 self->pvif->put(self->scratch, evt->
dbe_mask, pfl);
52 self->hadevent_PROPERTY =
true;
54 self->hadevent_VALUE =
true;
56 if(self->hadevent_VALUE && self->hadevent_PROPERTY) {
57 self->interested_iterating =
true;
59 FOREACH(PDBSinglePV::interested_t::const_iterator, it, end, self->interested) {
62 mon.
post(G, self->scratch);
65 while(!self->interested_add.empty()) {
66 PDBSinglePV::interested_t::iterator first(self->interested_add.begin());
67 self->interested.insert(*first);
68 self->interested_add.erase(first);
71 temp.swap(self->interested_remove);
72 for(PDBSinglePV::interested_remove_t::iterator it(temp.begin()),
73 end(temp.end()); it != end; ++it)
75 self->interested.erase(static_cast<PDBSingleMonitor*>(it->get()));
78 self->interested_iterating =
false;
80 self->finalizeMonitor();
84 }
catch(std::tr1::bad_weak_ptr&){
90 }
catch(std::exception& e){
91 std::cerr<<
"Unhandled exception in pdb_single_event(): "<<e.what()<<
"\n" 97 const PDBProvider::shared_pointer& prov)
100 ,interested_iterating(
false)
103 ,hadevent_VALUE(
false)
104 ,hadevent_PROPERTY(
false)
106 this->chan.
swap(chan);
111 pvif.reset(
builder->attach(this->chan, complete, temp));
127 pva::Channel::shared_pointer
129 const pva::ChannelRequester::shared_pointer& req)
133 ret->cred.update(req);
135 ret->aspvt.add(
chan, ret->cred);
194 const pva::ChannelRequester::shared_pointer& req)
220 pva::ChannelPut::shared_pointer
222 pva::ChannelPutRequester::shared_pointer
const &
requester,
223 pvd::PVStructure::shared_pointer
const & pvRequest)
225 PDBSinglePut::shared_pointer ret(
new PDBSinglePut(shared_from_this(), requester, pvRequest));
231 pva::Monitor::shared_pointer
233 pva::MonitorRequester::shared_pointer
const &
requester,
234 pvd::PVStructure::shared_pointer
const & pvRequest)
240 ret->connect(G,
pv->complete);
246 int single_put_callback(
struct processNotify *notify,notifyPutType
type)
250 if(notify->status!=notifyOK)
return 0;
255 case putDisabledType:
260 self->wait_pvif->get(*self->wait_changed);
264 self->wait_pvif->get(*self->wait_changed);
271 void single_done_callback(
struct processNotify *notify)
277 if(epics::atomic::compareAndSwap(self->notifyBusy, 1, 0)==0) {
278 std::cerr<<
"PDBSinglePut dbNotify state error?\n";
281 switch(notify->status) {
289 case notifyPutDisabled:
294 PDBSinglePut::requester_type::shared_pointer req(self->requester.lock());
296 req->putDone(sts, self->shared_from_this());
300 const pva::ChannelPutRequester::shared_pointer &
requester,
301 const pvd::PVStructure::shared_pointer &pvReq)
303 ,requester(requester)
304 ,changed(new
pvd::BitSet(channel->
fielddesc->getNumberFields()))
306 ,pvif(channel->
pv->builder->attach(channel->
pv->chan, pvf,
FieldName()))
308 ,doProc(
PVIF::ProcPassive)
312 dbChannel *chan = channel->pv->chan;
315 getS<pvd::boolean>(pvReq,
"record._options.block",
doWait);
316 }
catch(std::runtime_error& e) {
321 if(getS<std::string>(pvReq,
"record._options.process", proccmd)) {
322 if(proccmd==
"true") {
324 }
else if(proccmd==
"false") {
327 }
else if(proccmd==
"passive") {
335 notify.usrPvt = (
void*)
this;
337 notify.putCallback = &single_put_callback;
338 notify.doneCallback = &single_done_callback;
348 pvd::BitSet::shared_pointer
const &
changed)
350 dbChannel *chan =
channel->pv->chan;
351 dbFldDes *fld = dbChannelFldDes(chan);
354 if(!
channel->aspvt.canWrite()) {
363 }
catch(std::exception& e) {
364 std::ostringstream strm;
365 strm<<
"Failed to put link field "<<dbChannelName(chan)<<
"."<<fld->
name<<
" : "<<e.what()<<
"\n";
374 unsigned mask = putpvif->dbe(*changed);
377 requester_type::shared_pointer req(
requester.lock());
382 if(epics::atomic::compareAndSwap(
notifyBusy, 0, 1)!=0)
383 throw std::logic_error(
"Previous put() not complete");
385 notify.requestType = (mask&
DBE_VALUE) ? putProcessRequest : processRequest;
398 putpvif->get(*changed,
doProc);
400 }
catch(std::runtime_error& e){
404 requester_type::shared_pointer req(
requester.lock());
406 req->putDone(ret, shared_from_this());
411 if(epics::atomic::compareAndSwap(
notifyBusy, 1, 2)==1) {
430 requester_type::shared_pointer req(
requester.lock());
436 const requester_t::shared_pointer&
requester,
437 const pvd::PVStructure::shared_pointer& pvReq)
457 pv->addMonitor(
this);
464 pv->removeMonitor(
this);
bool interested_iterating
virtual void onStart() OVERRIDE FINAL
PVScalar is the base class for each scalar field.
PDBSingleChannel(const PDBSinglePV::shared_pointer &pv, const epics::pvAccess::ChannelRequester::shared_pointer &req)
p2p::auto_ptr< PVIF > pvif
epics::pvData::BitSetPtr changed
#define assert(exp)
Declare that a condition should be true.
dbEventSubscription subscript
static size_t num_instances
shared_pointer shared_from_this()
virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut(epics::pvAccess::ChannelPutRequester::shared_pointer const &requester, epics::pvData::PVStructure::shared_pointer const &pvRequest) OVERRIDE FINAL
#define FOREACH(ITERTYPE, IT, END, C)
static Status error(const std::string &m)
PDBSingleMonitor(const PDBSinglePV::shared_pointer &pv, const requester_t::shared_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq)
virtual ~PDBSingleChannel()
PDBSingleChannel::shared_pointer channel
interested_remove_t interested_remove
virtual void put(epics::pvData::PVStructure::shared_pointer const &pvPutStructure, epics::pvData::BitSet::shared_pointer const &putBitSet) OVERRIDE FINAL
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
virtual void onStop() OVERRIDE FINAL
pvd::StructureConstPtr type
virtual void get() OVERRIDE FINAL
virtual void destroy() OVERRIDE FINAL
p2p::auto_ptr< PVIF > pvif
p2p::auto_ptr< PVIF > wait_pvif
#define SHOW_EXCEPTION(EI)
epicsGuard< epicsMutex > Guard
PDBProvider::shared_pointer provider
epics::pvData::StructureConstPtr fielddesc
virtual ~PDBSingleMonitor()
std::vector< std::vector< char > > groups
void removeMonitor(PDBSingleMonitor *)
shared_pointer shared_from_this()
requester_t::weak_pointer requester
This class implements introspection object for a structure.
virtual epics::pvAccess::Channel::shared_pointer connect(const std::tr1::shared_ptr< PDBProvider > &prov, const epics::pvAccess::ChannelRequester::shared_pointer &req) OVERRIDE FINAL
void create(dbEventCtx ctx, dbChannel *ch, EVENTFUNC *fn, unsigned mask)
static size_t num_instances
epics::pvData::PVStructurePtr complete
static size_t num_instances
p2p::auto_ptr< ScalarBuilder > builder
void addMonitor(PDBSingleMonitor *)
interested_t interested_add
virtual epics::pvData::Monitor::shared_pointer createMonitor(epics::pvData::MonitorRequester::shared_pointer const &requester, epics::pvData::PVStructure::shared_pointer const &pvRequest) OVERRIDE FINAL
bool post(guard_t &guard, const epics::pvData::BitSet &updated, no_overflow)
post update if queue not full, if full return false w/o overflow
std::set< BaseMonitor::shared_pointer > interested_remove_t
virtual void requestUpdate() OVERRIDE FINAL
epics::pvData::PVStructurePtr pvf
static size_t num_instances
epics::pvData::BitSetPtr wait_changed
virtual void cancel() OVERRIDE FINAL
const requester_type::weak_pointer requester
FORCE_INLINE const PVDataCreatePtr & getPVDataCreate()
PDBSinglePV(DBCH &chan, const PDBProvider::shared_pointer &prov)
const epics::pvData::StructureConstPtr fielddesc
PDBSinglePut(const PDBSingleChannel::shared_pointer &channel, const epics::pvAccess::ChannelPutRequester::shared_pointer &requester, const epics::pvData::PVStructure::shared_pointer &pvReq)