Rename pvAccessApp to src, adjust Makefiles
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
SRC_DIRS += $(PVACCESS_SRC)/ca
|
||||
|
||||
INC += caProvider.h
|
||||
INC += caChannel.h
|
||||
|
||||
LIBSRCS += caProvider.cpp
|
||||
LIBSRCS += caChannel.cpp
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* pvAccessCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef CACHANNEL_H
|
||||
#define CACHANNEL_H
|
||||
|
||||
#include <pv/pvAccess.h>
|
||||
|
||||
/* for CA */
|
||||
#include <cadef.h>
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
namespace ca {
|
||||
|
||||
class CAChannel :
|
||||
public Channel,
|
||||
public std::tr1::enable_shared_from_this<CAChannel>
|
||||
{
|
||||
|
||||
public:
|
||||
POINTER_DEFINITIONS(CAChannel);
|
||||
|
||||
static shared_pointer create(ChannelProvider::shared_pointer const & channelProvider,
|
||||
epics::pvData::String const & channelName,
|
||||
short priority,
|
||||
ChannelRequester::shared_pointer const & channelRequester);
|
||||
|
||||
virtual ~CAChannel();
|
||||
|
||||
void connected();
|
||||
void disconnected();
|
||||
|
||||
chid getChannelID();
|
||||
chtype getNativeType();
|
||||
unsigned getElementCount();
|
||||
|
||||
/* --------------- epics::pvAccess::Channel --------------- */
|
||||
|
||||
virtual std::tr1::shared_ptr<ChannelProvider> getProvider();
|
||||
virtual epics::pvData::String getRemoteAddress();
|
||||
virtual ConnectionState getConnectionState();
|
||||
virtual epics::pvData::String getChannelName();
|
||||
virtual std::tr1::shared_ptr<ChannelRequester> getChannelRequester();
|
||||
virtual bool isConnected();
|
||||
|
||||
virtual void getField(GetFieldRequester::shared_pointer const & requester,epics::pvData::String const & subField);
|
||||
|
||||
virtual AccessRights getAccessRights(epics::pvData::PVField::shared_pointer const & pvField);
|
||||
|
||||
virtual ChannelProcess::shared_pointer createChannelProcess(
|
||||
ChannelProcessRequester::shared_pointer const & channelProcessRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
|
||||
virtual ChannelGet::shared_pointer createChannelGet(
|
||||
ChannelGetRequester::shared_pointer const & channelGetRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
|
||||
virtual ChannelPut::shared_pointer createChannelPut(
|
||||
ChannelPutRequester::shared_pointer const & channelPutRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
|
||||
virtual ChannelPutGet::shared_pointer createChannelPutGet(
|
||||
ChannelPutGetRequester::shared_pointer const & channelPutGetRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
|
||||
virtual ChannelRPC::shared_pointer createChannelRPC(
|
||||
ChannelRPCRequester::shared_pointer const & channelRPCRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
|
||||
virtual epics::pvData::Monitor::shared_pointer createMonitor(
|
||||
epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
|
||||
virtual ChannelArray::shared_pointer createChannelArray(
|
||||
ChannelArrayRequester::shared_pointer const & channelArrayRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
|
||||
virtual void printInfo();
|
||||
|
||||
virtual void printInfo(epics::pvData::StringBuilder out);
|
||||
|
||||
/* --------------- epics::pvData::Requester --------------- */
|
||||
|
||||
virtual epics::pvData::String getRequesterName();
|
||||
|
||||
virtual void message(epics::pvData::String const & message, epics::pvData::MessageType messageType);
|
||||
|
||||
/* --------------- epics::pvData::Destroyable --------------- */
|
||||
|
||||
virtual void destroy();
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void registerRequest(ChannelRequest::shared_pointer const & request);
|
||||
void unregisterRequest(ChannelRequest::shared_pointer const & request);
|
||||
|
||||
private:
|
||||
|
||||
CAChannel(epics::pvData::String const & channelName,
|
||||
ChannelProvider::shared_pointer const & channelProvider,
|
||||
ChannelRequester::shared_pointer const & channelRequester);
|
||||
void activate(short priority);
|
||||
|
||||
epics::pvData::String channelName;
|
||||
|
||||
ChannelProvider::shared_pointer channelProvider;
|
||||
ChannelRequester::shared_pointer channelRequester;
|
||||
|
||||
chid channelID;
|
||||
chtype channelType;
|
||||
unsigned elementCount;
|
||||
epics::pvData::Structure::const_shared_pointer structure;
|
||||
|
||||
epics::pvData::Mutex requestsMutex;
|
||||
// TODO std::unordered_map
|
||||
// void* is not the nicest thing, but there is no fast weak_ptr==
|
||||
typedef std::map<void*, ChannelRequest::weak_pointer> RequestsList;
|
||||
RequestsList requests;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CAChannelGet :
|
||||
public ChannelGet,
|
||||
public std::tr1::enable_shared_from_this<CAChannelGet>
|
||||
{
|
||||
|
||||
public:
|
||||
POINTER_DEFINITIONS(CAChannelGet);
|
||||
|
||||
static ChannelGet::shared_pointer create(CAChannel::shared_pointer const & channel,
|
||||
ChannelGetRequester::shared_pointer const & channelGetRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
|
||||
virtual ~CAChannelGet();
|
||||
|
||||
void getDone(struct event_handler_args &args);
|
||||
|
||||
/* --------------- epics::pvAccess::ChannelGet --------------- */
|
||||
|
||||
virtual void get(bool lastRequest);
|
||||
|
||||
/* --------------- epics::pvData::Destroyable --------------- */
|
||||
|
||||
virtual void destroy();
|
||||
|
||||
/* --------------- epics::pvData::Lockable --------------- */
|
||||
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
|
||||
private:
|
||||
|
||||
CAChannelGet(CAChannel::shared_pointer const & _channel,
|
||||
ChannelGetRequester::shared_pointer const & _channelGetRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
void activate();
|
||||
|
||||
CAChannel::shared_pointer channel;
|
||||
ChannelGetRequester::shared_pointer channelGetRequester;
|
||||
chtype getType;
|
||||
|
||||
epics::pvData::PVStructure::shared_pointer pvStructure;
|
||||
epics::pvData::BitSet::shared_pointer bitSet;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CAChannelPut :
|
||||
public ChannelPut,
|
||||
public std::tr1::enable_shared_from_this<CAChannelPut>
|
||||
{
|
||||
|
||||
public:
|
||||
POINTER_DEFINITIONS(CAChannelPut);
|
||||
|
||||
static ChannelPut::shared_pointer create(CAChannel::shared_pointer const & channel,
|
||||
ChannelPutRequester::shared_pointer const & channelPutRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
|
||||
virtual ~CAChannelPut();
|
||||
|
||||
void putDone(struct event_handler_args &args);
|
||||
void getDone(struct event_handler_args &args);
|
||||
|
||||
/* --------------- epics::pvAccess::ChannelPut --------------- */
|
||||
|
||||
virtual void put(bool lastRequest);
|
||||
virtual void get();
|
||||
|
||||
/* --------------- epics::pvData::Destroyable --------------- */
|
||||
|
||||
virtual void destroy();
|
||||
|
||||
/* --------------- epics::pvData::Lockable --------------- */
|
||||
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
|
||||
private:
|
||||
|
||||
CAChannelPut(CAChannel::shared_pointer const & _channel,
|
||||
ChannelPutRequester::shared_pointer const & _channelPutRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
void activate();
|
||||
|
||||
CAChannel::shared_pointer channel;
|
||||
ChannelPutRequester::shared_pointer channelPutRequester;
|
||||
chtype getType;
|
||||
|
||||
epics::pvData::PVStructure::shared_pointer pvStructure;
|
||||
epics::pvData::BitSet::shared_pointer bitSet;
|
||||
};
|
||||
|
||||
|
||||
class CAChannelMonitor :
|
||||
public epics::pvData::Monitor,
|
||||
public std::tr1::enable_shared_from_this<CAChannelMonitor>
|
||||
{
|
||||
|
||||
public:
|
||||
POINTER_DEFINITIONS(CAChannelMonitor);
|
||||
|
||||
static epics::pvData::Monitor::shared_pointer create(CAChannel::shared_pointer const & channel,
|
||||
epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
|
||||
virtual ~CAChannelMonitor();
|
||||
|
||||
void subscriptionEvent(struct event_handler_args &args);
|
||||
|
||||
/* --------------- epics::pvData::Monitor --------------- */
|
||||
|
||||
virtual epics::pvData::Status start();
|
||||
virtual epics::pvData::Status stop();
|
||||
virtual epics::pvData::MonitorElementPtr poll();
|
||||
virtual void release(epics::pvData::MonitorElementPtr const & monitorElement);
|
||||
|
||||
/* --------------- epics::pvData::Destroyable --------------- */
|
||||
|
||||
virtual void destroy();
|
||||
|
||||
private:
|
||||
|
||||
CAChannelMonitor(CAChannel::shared_pointer const & _channel,
|
||||
epics::pvData::MonitorRequester::shared_pointer const & _monitorRequester,
|
||||
epics::pvData::PVStructure::shared_pointer const & pvRequest);
|
||||
void activate();
|
||||
|
||||
CAChannel::shared_pointer channel;
|
||||
epics::pvData::MonitorRequester::shared_pointer monitorRequester;
|
||||
chtype getType;
|
||||
|
||||
epics::pvData::PVStructure::shared_pointer pvStructure;
|
||||
epics::pvData::BitSet::shared_pointer changedBitSet;
|
||||
epics::pvData::BitSet::shared_pointer overrunBitSet;
|
||||
evid eventID;
|
||||
|
||||
epics::pvData::Mutex mutex;
|
||||
int count;
|
||||
|
||||
epics::pvData::MonitorElement::shared_pointer element;
|
||||
epics::pvData::MonitorElement::shared_pointer nullElement;
|
||||
|
||||
// TODO remove
|
||||
Monitor::shared_pointer thisPointer;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* CACHANNEL_H */
|
||||
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* pvAccessCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
/* for CA */
|
||||
#include <cadef.h>
|
||||
#include <epicsSignal.h>
|
||||
|
||||
#include <pv/logger.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <pv/caProvider.h>
|
||||
#include <pv/caChannel.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvAccess::ca;
|
||||
|
||||
#define EXCEPTION_GUARD(code) try { code; } \
|
||||
catch (std::exception &e) { LOG(logLevelError, "Unhandled exception caught from client code at %s:%d: %s", __FILE__, __LINE__, e.what()); } \
|
||||
catch (...) { LOG(logLevelError, "Unhandled exception caught from client code at %s:%d.", __FILE__, __LINE__); }
|
||||
|
||||
String CAChannelProvider::PROVIDER_NAME = "ca";
|
||||
|
||||
CAChannelProvider::CAChannelProvider()
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
CAChannelProvider::~CAChannelProvider()
|
||||
{
|
||||
}
|
||||
|
||||
epics::pvData::String CAChannelProvider::getProviderName()
|
||||
{
|
||||
return PROVIDER_NAME;
|
||||
}
|
||||
|
||||
ChannelFind::shared_pointer CAChannelProvider::channelFind(
|
||||
epics::pvData::String const & channelName,
|
||||
ChannelFindRequester::shared_pointer const & channelFindRequester)
|
||||
{
|
||||
if (channelName.empty())
|
||||
throw std::invalid_argument("empty channel name");
|
||||
|
||||
if (!channelFindRequester)
|
||||
throw std::invalid_argument("null requester");
|
||||
|
||||
Status errorStatus(Status::STATUSTYPE_ERROR, "not implemented");
|
||||
ChannelFind::shared_pointer nullChannelFind;
|
||||
EXCEPTION_GUARD(channelFindRequester->channelFindResult(errorStatus, nullChannelFind, false));
|
||||
return nullChannelFind;
|
||||
}
|
||||
|
||||
Channel::shared_pointer CAChannelProvider::createChannel(
|
||||
epics::pvData::String const & channelName,
|
||||
ChannelRequester::shared_pointer const & channelRequester,
|
||||
short priority)
|
||||
{
|
||||
static String emptyString;
|
||||
return createChannel(channelName, channelRequester, priority, emptyString);
|
||||
}
|
||||
|
||||
Channel::shared_pointer CAChannelProvider::createChannel(
|
||||
epics::pvData::String const & channelName,
|
||||
ChannelRequester::shared_pointer const & channelRequester,
|
||||
short priority,
|
||||
epics::pvData::String const & address)
|
||||
{
|
||||
if (!address.empty())
|
||||
throw std::invalid_argument("CA does not support 'address' parameter");
|
||||
|
||||
return CAChannel::create(shared_from_this(), channelName, priority, channelRequester);
|
||||
}
|
||||
|
||||
void CAChannelProvider::configure(epics::pvData::PVStructure::shared_pointer /*configuration*/)
|
||||
{
|
||||
}
|
||||
|
||||
void CAChannelProvider::flush()
|
||||
{
|
||||
}
|
||||
|
||||
void CAChannelProvider::poll()
|
||||
{
|
||||
}
|
||||
|
||||
void CAChannelProvider::destroy()
|
||||
{
|
||||
Lock lock(channelsMutex);
|
||||
{
|
||||
while (!channels.empty())
|
||||
{
|
||||
Channel::shared_pointer channel = channels.rbegin()->second.lock();
|
||||
if (channel)
|
||||
channel->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/* Destroy CA Context */
|
||||
ca_context_destroy();
|
||||
}
|
||||
|
||||
void CAChannelProvider::registerChannel(Channel::shared_pointer const & channel)
|
||||
{
|
||||
Lock lock(channelsMutex);
|
||||
channels[channel.get()] = Channel::weak_pointer(channel);
|
||||
}
|
||||
|
||||
void CAChannelProvider::unregisterChannel(Channel::shared_pointer const & channel)
|
||||
{
|
||||
Lock lock(channelsMutex);
|
||||
channels.erase(channel.get());
|
||||
}
|
||||
|
||||
void CAChannelProvider::initialize()
|
||||
{
|
||||
/* Create Channel Access */
|
||||
int result = ca_context_create(ca_enable_preemptive_callback);
|
||||
if (result != ECA_NORMAL) {
|
||||
throw std::runtime_error(std::string("CA error %s occurred while trying "
|
||||
"to start channel access:") + ca_message(result));
|
||||
}
|
||||
|
||||
// TODO create a ca_poll thread, if ca_disable_preemptive_callback
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO global static variable (de/initialization order not guaranteed)
|
||||
static Mutex mutex;
|
||||
static CAChannelProvider::shared_pointer sharedProvider;
|
||||
|
||||
class CAChannelProviderFactoryImpl : public ChannelProviderFactory
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(CAChannelProviderFactoryImpl);
|
||||
|
||||
virtual epics::pvData::String getFactoryName()
|
||||
{
|
||||
return CAChannelProvider::PROVIDER_NAME;
|
||||
}
|
||||
|
||||
virtual ChannelProvider::shared_pointer sharedInstance()
|
||||
{
|
||||
Lock guard(mutex);
|
||||
if (!sharedProvider.get())
|
||||
{
|
||||
try {
|
||||
sharedProvider.reset(new CAChannelProvider());
|
||||
} catch (std::exception &e) {
|
||||
LOG(logLevelError, "Unhandled exception caught at %s:%d: %s", __FILE__, __LINE__, e.what());
|
||||
} catch (...) {
|
||||
LOG(logLevelError, "Unhandled exception caught at %s:%d.", __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
return sharedProvider;
|
||||
}
|
||||
|
||||
virtual ChannelProvider::shared_pointer newInstance()
|
||||
{
|
||||
try {
|
||||
return ChannelProvider::shared_pointer(new CAChannelProvider());
|
||||
} catch (std::exception &e) {
|
||||
LOG(logLevelError, "Unhandled exception caught at %s:%d: %s", __FILE__, __LINE__, e.what());
|
||||
return ChannelProvider::shared_pointer();
|
||||
} catch (...) {
|
||||
LOG(logLevelError, "Unhandled exception caught at %s:%d.", __FILE__, __LINE__);
|
||||
return ChannelProvider::shared_pointer();
|
||||
}
|
||||
}
|
||||
|
||||
void destroySharedInstance()
|
||||
{
|
||||
sharedProvider->destroy();
|
||||
sharedProvider.reset();
|
||||
}
|
||||
};
|
||||
|
||||
static CAChannelProviderFactoryImpl::shared_pointer factory;
|
||||
|
||||
void CAClientFactory::start()
|
||||
{
|
||||
epicsSignalInstallSigAlarmIgnore();
|
||||
epicsSignalInstallSigPipeIgnore();
|
||||
|
||||
Lock guard(mutex);
|
||||
if (!factory.get())
|
||||
factory.reset(new CAChannelProviderFactoryImpl());
|
||||
|
||||
registerChannelProviderFactory(factory);
|
||||
}
|
||||
|
||||
void CAClientFactory::stop()
|
||||
{
|
||||
Lock guard(mutex);
|
||||
|
||||
if (factory.get())
|
||||
{
|
||||
unregisterChannelProviderFactory(factory);
|
||||
factory->destroySharedInstance();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* pvAccessCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef CAPROVIDER_H
|
||||
#define CAPROVIDER_H
|
||||
|
||||
#include <pv/pvAccess.h>
|
||||
#include <map>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
namespace ca {
|
||||
|
||||
class epicsShareClass CAChannelProvider :
|
||||
public ChannelProvider,
|
||||
public std::tr1::enable_shared_from_this<CAChannelProvider>
|
||||
{
|
||||
public:
|
||||
|
||||
static epics::pvData::String PROVIDER_NAME;
|
||||
|
||||
CAChannelProvider();
|
||||
virtual ~CAChannelProvider();
|
||||
|
||||
/* --------------- epics::pvAccess::ChannelProvider --------------- */
|
||||
|
||||
virtual epics::pvData::String getProviderName();
|
||||
|
||||
virtual ChannelFind::shared_pointer channelFind(
|
||||
epics::pvData::String const & channelName,
|
||||
ChannelFindRequester::shared_pointer const & channelFindRequester);
|
||||
|
||||
|
||||
virtual Channel::shared_pointer createChannel(
|
||||
epics::pvData::String const & channelName,
|
||||
ChannelRequester::shared_pointer const & channelRequester,
|
||||
short priority);
|
||||
|
||||
virtual Channel::shared_pointer createChannel(
|
||||
epics::pvData::String const & channelName,
|
||||
ChannelRequester::shared_pointer const & channelRequester,
|
||||
short priority,
|
||||
epics::pvData::String const & address);
|
||||
|
||||
virtual void configure(epics::pvData::PVStructure::shared_pointer configuration);
|
||||
virtual void flush();
|
||||
virtual void poll();
|
||||
|
||||
virtual void destroy();
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void registerChannel(Channel::shared_pointer const & channel);
|
||||
void unregisterChannel(Channel::shared_pointer const & channel);
|
||||
|
||||
private:
|
||||
|
||||
void initialize();
|
||||
|
||||
epics::pvData::Mutex channelsMutex;
|
||||
// TODO std::unordered_map
|
||||
// void* is not the nicest thing, but there is no fast weak_ptr==
|
||||
typedef std::map<void*, Channel::weak_pointer> ChannelList;
|
||||
ChannelList channels;
|
||||
};
|
||||
|
||||
|
||||
class epicsShareClass CAClientFactory
|
||||
{
|
||||
public:
|
||||
static void start();
|
||||
static void stop();
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* CAPROVIDER_H */
|
||||
Reference in New Issue
Block a user