more
This commit is contained in:
@ -134,10 +134,11 @@ struct BaseChannel : public epics::pvAccess::Channel
|
||||
* Derived class may use onStart(), onStop(), and requestUpdate()
|
||||
* to react to subscriber events.
|
||||
*/
|
||||
struct BaseMonitor : public epics::pvAccess::Monitor,
|
||||
public std::tr1::enable_shared_from_this<BaseMonitor>
|
||||
struct BaseMonitor : public epics::pvAccess::Monitor
|
||||
{
|
||||
POINTER_DEFINITIONS(BaseMonitor);
|
||||
weak_pointer weakself;
|
||||
inline shared_pointer shared_from_this() { return shared_pointer(weakself); }
|
||||
|
||||
typedef epics::pvAccess::MonitorRequester requester_t;
|
||||
|
||||
@ -175,13 +176,12 @@ public:
|
||||
{
|
||||
epics::pvData::StructureConstPtr dtype(value->getStructure());
|
||||
epics::pvData::PVDataCreatePtr create(epics::pvData::getPVDataCreate());
|
||||
BaseMonitor::shared_pointer self;
|
||||
BaseMonitor::shared_pointer self(shared_from_this());
|
||||
requester_t::shared_pointer req;
|
||||
{
|
||||
guard_t G(lock);
|
||||
assert(!complete); // can't call twice
|
||||
|
||||
self = shared_from_this();
|
||||
req = requester;
|
||||
|
||||
complete = value;
|
||||
|
@ -100,6 +100,7 @@ PDBProvider::PDBProvider()
|
||||
const size_t nchans = info.members.size();
|
||||
|
||||
PDBGroupPV::shared_pointer pv(new PDBGroupPV());
|
||||
pv->weakself = pv;
|
||||
pv->name = info.name;
|
||||
pv->attachments.resize(nchans);
|
||||
//pv->chan.resize(nchans);
|
||||
@ -236,6 +237,9 @@ PDBProvider::createChannel(std::string const & channelName,
|
||||
DBCH chan(pchan);
|
||||
pv.reset(new PDBSinglePV(chan, shared_from_this()));
|
||||
transient_pv_map.insert(channelName, pv);
|
||||
PDBSinglePV::shared_pointer spv = std::tr1::static_pointer_cast<PDBSinglePV>(pv);
|
||||
spv->weakself = spv;
|
||||
spv->activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,11 @@
|
||||
#include "pvif.h"
|
||||
#include "pdb.h"
|
||||
|
||||
struct PDBGroupPV : public PDBPV, public std::tr1::enable_shared_from_this<PDBGroupPV>
|
||||
struct PDBGroupPV : public PDBPV
|
||||
{
|
||||
POINTER_DEFINITIONS(PDBGroupPV);
|
||||
weak_pointer weakself;
|
||||
inline shared_pointer shared_from_this() { return shared_pointer(weakself); }
|
||||
|
||||
std::string name;
|
||||
epics::pvData::shared_vector<DBCH> chan;
|
||||
|
@ -20,9 +20,9 @@ static
|
||||
void pdb_single_event(void *user_arg, struct dbChannel *chan,
|
||||
int eventsRemaining, struct db_field_log *pfl)
|
||||
{
|
||||
PDBSinglePV::Event *evt=(PDBSinglePV::Event*)user_arg;
|
||||
DBEvent *evt=(DBEvent*)user_arg;
|
||||
try{
|
||||
PDBSinglePV::shared_pointer self(std::tr1::static_pointer_cast<PDBSinglePV>(evt->self->shared_from_this()));
|
||||
PDBSinglePV::shared_pointer self(std::tr1::static_pointer_cast<PDBSinglePV>(((PDBSinglePV*)evt->self)->shared_from_this()));
|
||||
{
|
||||
Guard G(self->lock); // TODO: lock order?
|
||||
|
||||
@ -53,39 +53,14 @@ void pdb_single_event(void *user_arg, struct dbChannel *chan,
|
||||
}
|
||||
}
|
||||
|
||||
PDBSinglePV::Event::Event(PDBSinglePV *pv, unsigned mask)
|
||||
:self(pv)
|
||||
,subscript(NULL)
|
||||
,dbe_mask(mask)
|
||||
{
|
||||
}
|
||||
|
||||
PDBSinglePV::Event::~Event() {
|
||||
db_cancel_event(subscript);
|
||||
}
|
||||
|
||||
void PDBSinglePV::Event::enable()
|
||||
{
|
||||
assert(!subscript);
|
||||
subscript = db_add_event(self->provider->event_context,
|
||||
self->chan,
|
||||
&pdb_single_event,
|
||||
(void*)this,
|
||||
dbe_mask);
|
||||
if(!subscript)
|
||||
throw std::runtime_error("Failed to subscribe to dbEvent");
|
||||
}
|
||||
|
||||
PDBSinglePV::PDBSinglePV(DBCH& chan,
|
||||
const PDBProvider::shared_pointer& prov)
|
||||
:provider(prov)
|
||||
,evt_VALUE(this, DBE_VALUE|DBE_ALARM)
|
||||
,evt_PROPERTY(this, DBE_PROPERTY)
|
||||
,evt_VALUE(this)
|
||||
,evt_PROPERTY(this)
|
||||
,hadevent(false)
|
||||
{
|
||||
this->chan.swap(chan);
|
||||
evt_VALUE.enable();
|
||||
evt_PROPERTY.enable();
|
||||
fielddesc = PVIF::dtype(this->chan);
|
||||
|
||||
complete = pvd::getPVDataCreate()->createPVStructure(fielddesc);
|
||||
@ -101,7 +76,8 @@ PDBSinglePV::~PDBSinglePV()
|
||||
|
||||
void PDBSinglePV::activate()
|
||||
{
|
||||
|
||||
evt_VALUE.create(provider->event_context, this->chan, &pdb_single_event, DBE_VALUE|DBE_ALARM);
|
||||
evt_PROPERTY.create(provider->event_context, this->chan, &pdb_single_event, DBE_PROPERTY);
|
||||
}
|
||||
|
||||
pva::Channel::shared_pointer
|
||||
@ -117,6 +93,7 @@ PDBSingleChannel::PDBSingleChannel(const PDBSinglePV::shared_pointer& pv,
|
||||
:BaseChannel(dbChannelName(pv->chan), pv->provider, req, pv->fielddesc)
|
||||
,pv(pv)
|
||||
{
|
||||
assert(!!this->pv);
|
||||
}
|
||||
|
||||
void PDBSingleChannel::printInfo(std::ostream& out)
|
||||
@ -150,9 +127,10 @@ PDBSingleChannel::createMonitor(
|
||||
pva::MonitorRequester::shared_pointer const & requester,
|
||||
pvd::PVStructure::shared_pointer const & pvRequest)
|
||||
{
|
||||
pva::Monitor::shared_pointer ret(new PDBSingleMonitor(pv->shared_from_this(), requester, pvRequest));
|
||||
PDBSingleMonitor::shared_pointer ret(new PDBSingleMonitor(pv->shared_from_this(), requester, pvRequest));
|
||||
ret->weakself = ret;
|
||||
assert(!!pv->complete);
|
||||
((PDBSingleMonitor*)ret.get())->connect(pv->complete);
|
||||
ret->connect(pv->complete);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,11 @@
|
||||
|
||||
struct PDBSingleMonitor;
|
||||
|
||||
struct PDBSinglePV : public PDBPV, public std::tr1::enable_shared_from_this<PDBSinglePV>
|
||||
struct PDBSinglePV : public PDBPV
|
||||
{
|
||||
POINTER_DEFINITIONS(PDBSinglePV);
|
||||
weak_pointer weakself;
|
||||
inline shared_pointer shared_from_this() { return shared_pointer(weakself); }
|
||||
|
||||
/* this dbChannel is shared by all operations,
|
||||
* which is safe as it's modify-able field(s) (addr.pfield)
|
||||
@ -37,15 +39,7 @@ struct PDBSinglePV : public PDBPV, public std::tr1::enable_shared_from_this<PDBS
|
||||
typedef std::set<std::tr1::shared_ptr<PDBSingleMonitor> > interested_t;
|
||||
interested_t interested;
|
||||
|
||||
struct Event {
|
||||
PDBSinglePV *self;
|
||||
dbEventSubscription subscript;
|
||||
unsigned dbe_mask;
|
||||
Event(PDBSinglePV *m, unsigned mask);
|
||||
~Event();
|
||||
void enable();
|
||||
};
|
||||
Event evt_VALUE, evt_PROPERTY;
|
||||
DBEvent evt_VALUE, evt_PROPERTY;
|
||||
bool hadevent;
|
||||
|
||||
static size_t ninstances;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <dbChannel.h>
|
||||
#include <dbStaticLib.h>
|
||||
#include <dbLock.h>
|
||||
#include <dbEvent.h>
|
||||
|
||||
#include <pv/bitSet.h>
|
||||
#include <pv/pvData.h>
|
||||
@ -95,6 +96,25 @@ struct pdbRecordIterator {
|
||||
}
|
||||
};
|
||||
|
||||
struct DBEvent
|
||||
{
|
||||
dbEventSubscription subscript;
|
||||
unsigned dbe_mask;
|
||||
void *self;
|
||||
DBEvent(void* s) :subscript(NULL), self(s) {}
|
||||
~DBEvent() {destroy();}
|
||||
void create(dbEventCtx ctx, dbChannel *ch, EVENTFUNC *fn, unsigned mask)
|
||||
{
|
||||
subscript = db_add_event(ctx, ch, fn, this, mask);
|
||||
if(!subscript)
|
||||
throw std::runtime_error("Failed to subscribe to dbEvent");
|
||||
dbe_mask = mask;
|
||||
}
|
||||
void destroy() {
|
||||
if(subscript) db_cancel_event(subscript);
|
||||
}
|
||||
};
|
||||
|
||||
struct LocalFL
|
||||
{
|
||||
db_field_log *pfl;
|
||||
|
Reference in New Issue
Block a user