start PDB integration

This commit is contained in:
Michael Davidsaver
2016-03-02 10:49:06 -05:00
parent 48824ec333
commit 229f681d5c
8 changed files with 441 additions and 0 deletions

116
common/pvahelper.h Normal file
View File

@ -0,0 +1,116 @@
#ifndef PVAHELPER_H
#define PVAHELPER_H
#include <epicsGuard.h>
#include <pv/pvAccess.h>
struct BaseChannel : public epics::pvAccess::Channel
{
BaseChannel(const std::string& name,
const std::tr1::shared_ptr<epics::pvAccess::ChannelProvider>& prov,
const epics::pvAccess::ChannelRequester::shared_pointer& req,
const epics::pvData::StructureConstPtr& dtype
)
:pvname(name), provider(prov), requester(req), fielddesc(dtype)
{}
virtual ~BaseChannel() {}
epicsMutex lock;
typedef epicsGuard<epicsMutex> guard_t;
const std::string pvname;
std::tr1::shared_ptr<epics::pvAccess::ChannelProvider> provider;
epics::pvAccess::ChannelRequester::shared_pointer requester;
const epics::pvData::StructureConstPtr fielddesc;
// assume Requester methods not called after destory()
virtual std::string getRequesterName() { guard_t G(lock); return requester->getRequesterName(); }
virtual void destroy() { guard_t G(lock); provider.reset(); requester.reset(); }
virtual std::tr1::shared_ptr<epics::pvAccess::ChannelProvider> getProvider() { guard_t G(lock); return provider; }
virtual std::string getRemoteAddress() { guard_t G(lock); return requester->getRequesterName(); }
virtual ConnectionState getConnectionState() { return epics::pvAccess::Channel::CONNECTED; }
virtual std::string getChannelName() { return pvname; }
virtual std::tr1::shared_ptr<epics::pvAccess::ChannelRequester> getChannelRequester() { guard_t G(lock); return requester; }
virtual bool isConnected() { return getConnectionState()==epics::pvAccess::Channel::CONNECTED; }
virtual void getField(epics::pvAccess::GetFieldRequester::shared_pointer const & requester,std::string const & subField)
{ requester->getDone(epics::pvData::Status(), fielddesc); }
virtual epics::pvAccess::ChannelProcess::shared_pointer createChannelProcess(
epics::pvAccess::ChannelProcessRequester::shared_pointer const & requester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
epics::pvAccess::ChannelProcess::shared_pointer ret;
requester->channelProcessConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"), ret);
return ret;
}
virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet(
epics::pvAccess::ChannelGetRequester::shared_pointer const & requester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
epics::pvAccess::ChannelGet::shared_pointer ret;
requester->channelGetConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"),
ret, epics::pvData::StructureConstPtr());
return ret;
}
virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut(
epics::pvAccess::ChannelPutRequester::shared_pointer const & requester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
epics::pvAccess::ChannelPut::shared_pointer ret;
requester->channelPutConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"),
ret, epics::pvData::StructureConstPtr());
return ret;
}
virtual epics::pvAccess::ChannelPutGet::shared_pointer createChannelPutGet(
epics::pvAccess::ChannelPutGetRequester::shared_pointer const & requester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
epics::pvAccess::ChannelPutGet::shared_pointer ret;
requester->channelPutGetConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"),
ret, epics::pvData::StructureConstPtr(), epics::pvData::StructureConstPtr());
return ret;
}
virtual epics::pvAccess::ChannelRPC::shared_pointer createChannelRPC(
epics::pvAccess::ChannelRPCRequester::shared_pointer const & requester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
epics::pvAccess::ChannelRPC::shared_pointer ret;
requester->channelRPCConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"), ret);
return ret;
}
virtual epics::pvData::Monitor::shared_pointer createMonitor(
epics::pvData::MonitorRequester::shared_pointer const & requester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
epics::pvData::Monitor::shared_pointer ret;
requester->monitorConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"),
ret, epics::pvData::StructureConstPtr());
return ret;
}
virtual epics::pvAccess::ChannelArray::shared_pointer createChannelArray(
epics::pvAccess::ChannelArrayRequester::shared_pointer const & requester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
epics::pvAccess::ChannelArray::shared_pointer ret;
requester->channelArrayConnect(epics::pvData::Status(epics::pvData::Status::STATUSTYPE_FATAL, "Not implemented"),
ret, epics::pvData::Array::const_shared_pointer());
return ret;
}
virtual void printInfo() { printInfo(std::cout); }
virtual void printInfo(std::ostream& out) {
out<<"Channel '"<<pvname<<"' "<<getRemoteAddress()<<"\n";
}
};
#endif // PVAHELPER_H

View File

@ -7,7 +7,11 @@ include $(TOP)/configure/CONFIG
LIBRARY_HOST += pdbcore
USR_CPPFLAGS += -I$(TOP)/common -I$(TOP)/p2pApp
pdbcore_SRCS += pvif.cpp
pdbcore_SRCS += pdbsingle.cpp
pdbcore_SRCS += pdbgroup.cpp
pdbcore_LIBS += pvAccess pvData Com

57
pdbApp/pdb.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef PDB_H
#define PDB_H
#include "weakmap.h"
#include <pv/pvAccess.h>
struct PDBProvider;
struct PDBPV : public std::tr1::enable_shared_from_this<PDBPV>
{
POINTER_DEFINITIONS(PDBPV);
epics::pvData::StructureConstPtr fielddesc;
PDBPV(const epics::pvData::StructureConstPtr& fd) :fielddesc(fd) {}
virtual ~PDBPV() {}
virtual
epics::pvAccess::Channel::shared_pointer
connect(const std::tr1::shared_ptr<PDBProvider>& prov,
const epics::pvAccess::ChannelRequester::shared_pointer& req);
};
struct PDBProvider : public epics::pvAccess::ChannelProvider
{
POINTER_DEFINITIONS(PDBProvider);
virtual ~PDBProvider();
virtual void destroy();
virtual std::string getProviderName();
virtual epics::pvAccess::ChannelFind::shared_pointer channelFind(std::string const & channelName,
epics::pvAccess::ChannelFindRequester::shared_pointer const & channelFindRequester);
virtual epics::pvAccess::ChannelFind::shared_pointer channelList(epics::pvAccess::ChannelListRequester::shared_pointer const & channelListRequester);
virtual epics::pvAccess::Channel::shared_pointer createChannel(std::string const & channelName,
epics::pvAccess::ChannelRequester::shared_pointer const & channelRequester,
short priority = PRIORITY_DEFAULT);
virtual epics::pvAccess::Channel::shared_pointer createChannel(std::string const & channelName,
epics::pvAccess::ChannelRequester::shared_pointer const & channelRequester,
short priority, std::string const & address);
typedef std::map<std::string, epics::pvAccess::Channel::shared_pointer> persit_chan_map_t;
persit_chan_map_t persit_chan_map;
typedef weak_value_map<std::string, epics::pvAccess::Channel::shared_pointer> transient_chan_map_t;
transient_chan_map_t transient_chan_map;
};
struct PDBProviderFactory : public epics::pvAccess::ChannelProviderFactory
{
virtual ~PDBProviderFactory(){}
virtual std::string getFactoryName();
virtual epics::pvAccess::ChannelProvider::shared_pointer sharedInstance();
virtual epics::pvAccess::ChannelProvider::shared_pointer newInstance(const std::tr1::shared_ptr<epics::pvAccess::Configuration>&);
};
#endif // PDB_H

43
pdbApp/pdbgroup.cpp Normal file
View File

@ -0,0 +1,43 @@
#include <dbAccess.h>
#include "pdbgroup.h"
#include "pdb.h"
PDBGroupChannel::PDBGroupChannel(const PDBGroupPV::shared_pointer& pv,
const std::tr1::shared_ptr<epics::pvAccess::ChannelProvider>& prov,
const epics::pvAccess::ChannelRequester::shared_pointer& req)
:BaseChannel(dbChannelName(chan), prov, req, PVIF::dtype(dbChannelFinalFieldType(chan)))
{
this->chan.swap(chan); // we take ownership
}
epics::pvAccess::ChannelGet::shared_pointer
PDBGroupChannel::createChannelGet(
epics::pvAccess::ChannelGetRequester::shared_pointer const & requester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
epics::pvAccess::ChannelGet::shared_pointer ret(new PDBGroupGet(shared_from_this()));
requester->channelGetConnect(epics::pvData::Status(), ret, fielddesc);
return ret;
}
PDBGroupGet::PDBGroupGet(PDBGroupChannel::shared_pointer channel,
epics::pvAccess::ChannelGetRequester::shared_pointer requester)
:channel(channel)
,requester(requester)
,changed(new epics::pvData::BitSet(channel->fielddesc->getNumberFields()))
,pvf(epics::pvData::getPVDataCreate()->createPVStructure(channel->fielddesc))
,pvif(PVIF::attach(channel->chan, pvif))
{}
void PDBGroupGet::get()
{
changed->clear();
{
DBScanLocker L(channel->chan);
pvif->put(*changed, DBE_VALUE|DBE_ALARM|DBE_PROPERTY, NULL);
}
requester->getDone(epics::pvData::Status(), shared_from_this(), pvf, changed);
}

75
pdbApp/pdbgroup.h Normal file
View File

@ -0,0 +1,75 @@
#ifndef PDBGROUP_H
#define PDBGROUP_H
#include <dbAccess.h>
#include <dbEvent.h>
#include <dbLock.h>
#include <pv/pvAccess.h>
#include "pvahelper.h"
#include "pvif.h"
#include "pdb.h"
struct PDBGroupPV : public PDBPV
{
POINTER_DEFINITIONS(PDBGroupPV);
epics::pvData::shared_vector<DBCH> chan;
std::auto_ptr<dbLocker> locker;
PDBGroupPV(const std::vector<std::string>& names);
virtual
epics::pvAccess::Channel::shared_pointer
connect(const std::tr1::shared_ptr<PDBProvider>& prov,
const epics::pvAccess::ChannelRequester::shared_pointer& req);
};
struct PDBGroupChannel : public BaseChannel,
public std::tr1::enable_shared_from_this<PDBGroupChannel>
{
POINTER_DEFINITIONS(PDBGroupChannel);
PDBGroupPV::shared_pointer pv;
dbChannel *chan;
PDBGroupChannel(const PDBGroupPV::shared_pointer& pv,
const std::tr1::shared_ptr<epics::pvAccess::ChannelProvider>& prov,
const epics::pvAccess::ChannelRequester::shared_pointer& req);
virtual PDBGroupChannel() {}
virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet(
epics::pvAccess::ChannelGetRequester::shared_pointer const & channelGetRequester,
epics::pvData::PVStructure::shared_pointer const & pvRequest);
virtual void printInfo(std::ostream& out);
};
struct PDBGroupGet : public epics::pvAccess::ChannelGet,
public std::tr1::enable_shared_from_this<PDBGroupGet>
{
PDBGroupChannel::shared_pointer channel;
epics::pvAccess::ChannelGetRequester::shared_pointer requester;
epics::pvData::BitSetPtr changed;
epics::pvData::PVStructurePtr pvf;
std::auto_ptr<PVIF> pvif;
PDBGroupGet(PDBGroupChannel::shared_pointer channel,
epics::pvAccess::ChannelGetRequester::shared_pointer requester);
virtual ~PDBGroupGet() {}
virtual void destroy() { pvif.reset(); channel.reset(); requester.reset(); }
virtual void lock() {}
virtual void unlock() {}
virtual std::tr1::shared_ptr<Channel> getChannel() { return channel; }
virtual void cancel() {}
virtual void lastRequest() {}
virtual void get();
};
//struct PDBGroupPut : public epics::pvAccess::ChannelPut {};
//struct PDBGroupMonitor : public epics::pvData::Monitor {};
#endif // PDBGROUP_H

42
pdbApp/pdbsingle.cpp Normal file
View File

@ -0,0 +1,42 @@
#include <dbAccess.h>
#include "pdbsingle.h"
#include "pdb.h"
PDBSingleChannel::PDBSingleChannel(const PDBSinglePV::shared_pointer& pv,
const std::tr1::shared_ptr<epics::pvAccess::ChannelProvider>& prov,
const epics::pvAccess::ChannelRequester::shared_pointer& req)
:BaseChannel(dbChannelName(pv->chan), prov, req, pv->fielddesc)
,pv(pv)
{
}
epics::pvAccess::ChannelGet::shared_pointer
PDBSingleChannel::createChannelGet(
epics::pvAccess::ChannelGetRequester::shared_pointer const & requester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
epics::pvAccess::ChannelGet::shared_pointer ret(new PDBSingleGet(shared_from_this()));
requester->channelGetConnect(epics::pvData::Status(), ret, fielddesc);
return ret;
}
PDBSingleGet::PDBSingleGet(PDBSingleChannel::shared_pointer channel,
epics::pvAccess::ChannelGetRequester::shared_pointer requester)
:channel(channel)
,requester(requester)
,changed(new epics::pvData::BitSet(channel->fielddesc->getNumberFields()))
,pvf(epics::pvData::getPVDataCreate()->createPVStructure(channel->fielddesc))
,pvif(PVIF::attach(channel->chan, pvif))
{}
void PDBSingleGet::get()
{
changed->clear();
{
DBScanLocker L(channel->chan);
pvif->put(*changed, DBE_VALUE|DBE_ALARM|DBE_PROPERTY, NULL);
}
requester->getDone(epics::pvData::Status(), shared_from_this(), pvf, changed);
}

71
pdbApp/pdbsingle.h Normal file
View File

@ -0,0 +1,71 @@
#ifndef PDBSINGLE_H
#define PDBSINGLE_H
#include <dbAccess.h>
#include <dbEvent.h>
#include <pv/pvAccess.h>
#include "pvahelper.h"
#include "pvif.h"
#include "pdb.h"
struct PDBSinglePV : public PDBPV
{
POINTER_DEFINITIONS(PDBSinglePV);
DBCH chan;
PDBSinglePV(const char *name);
epics::pvAccess::Channel::shared_pointer
connect(const std::tr1::shared_ptr<PDBProvider>& prov,
const epics::pvAccess::ChannelRequester::shared_pointer& req);
};
struct PDBSingleChannel : public BaseChannel,
public std::tr1::enable_shared_from_this<PDBSingleChannel>
{
POINTER_DEFINITIONS(PDBSingleChannel);
PDBSinglePV::shared_pointer pv;
PDBSingleChannel(const PDBSinglePV::shared_pointer& pv,
const std::tr1::shared_ptr<epics::pvAccess::ChannelProvider>& prov,
const epics::pvAccess::ChannelRequester::shared_pointer& req);
virtual ~PDBSingleChannel() {}
virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet(
epics::pvAccess::ChannelGetRequester::shared_pointer const & channelGetRequester,
epics::pvData::PVStructure::shared_pointer const & pvRequest);
virtual void printInfo(std::ostream& out);
};
struct PDBSingleGet : public epics::pvAccess::ChannelGet,
public std::tr1::enable_shared_from_this<PDBSingleGet>
{
PDBSingleChannel::shared_pointer channel;
epics::pvAccess::ChannelGetRequester::shared_pointer requester;
epics::pvData::BitSetPtr changed;
epics::pvData::PVStructurePtr pvf;
std::auto_ptr<PVIF> pvif;
PDBSingleGet(PDBSingleChannel::shared_pointer channel,
epics::pvAccess::ChannelGetRequester::shared_pointer requester);
virtual ~PDBSingleGet() {}
virtual void destroy() { pvif.reset(); channel.reset(); requester.reset(); }
virtual void lock() {}
virtual void unlock() {}
virtual std::tr1::shared_ptr<epics::pvAccess::Channel> getChannel() { return channel; }
virtual void cancel() {}
virtual void lastRequest() {}
virtual void get();
};
//struct PDBSinglePut : public epics::pvAccess::ChannelPut {};
//struct PDBSingleMonitor : public epics::pvData::Monitor {};
#endif // PDBSINGLE_H

View File

@ -4,6 +4,7 @@
#include <map>
#include <dbChannel.h>
#include <dbStaticLib.h>
#include <pv/bitSet.h>
#include <pv/pvData.h>
@ -24,6 +25,38 @@ private:
DBCH& operator=(const DBCH&);
};
struct pdbRecordInfo {
DBENTRY ent;
pdbRecordInfo(const char *name)
{
dbInitEntry(pdbbase, &ent);
if(dbFindRecordPart(&ent, &name))
throw std::runtime_error(ent.message);
}
~pdbRecordInfo()
{
dbFinishEntry(&ent);
}
const char *info(const char *key, const char *def)
{
if(dbFindInfo(&ent, key))
return def;
return dbGetInfoString(&ent);
}
};
struct DBScanLocker
{
dbCommon *prec;
DBScanLocker(dbChannel *chan) :prec(dbChannelRecord(chan))
{ dbScanLock(prec); }
DBScanLocker(dbCommon *prec) :prec(prec)
{ dbScanLock(prec); }
~DBScanLocker()
{ dbScanUnlock(prec); }
};
struct PVIF {
PVIF(dbChannel *ch, const epics::pvData::PVStructurePtr& p);
virtual ~PVIF() {}