This commit is contained in:
Michael Davidsaver
2016-03-16 22:33:23 -04:00
parent 3215a280da
commit 65636d8d8c
6 changed files with 45 additions and 47 deletions

View File

@ -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;

View File

@ -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();
}
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;