start PDB integration
This commit is contained in:
116
common/pvahelper.h
Normal file
116
common/pvahelper.h
Normal 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
|
@ -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
57
pdbApp/pdb.h
Normal 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
43
pdbApp/pdbgroup.cpp
Normal 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
75
pdbApp/pdbgroup.h
Normal 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
42
pdbApp/pdbsingle.cpp
Normal 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
71
pdbApp/pdbsingle.h
Normal 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
|
@ -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() {}
|
||||
|
Reference in New Issue
Block a user