ca: monitor support

This commit is contained in:
Matej Sekoranja
2013-06-03 22:27:27 +02:00
parent 26c75b0092
commit d9eda7d908
2 changed files with 216 additions and 6 deletions
+161 -6
View File
@@ -322,13 +322,9 @@ ChannelRPC::shared_pointer CAChannel::createChannelRPC(
epics::pvData::Monitor::shared_pointer CAChannel::createMonitor(
epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
epics::pvData::PVStructure::shared_pointer const & /*pvRequest*/)
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
Status errorStatus(Status::STATUSTYPE_ERROR, "not implemented");
Monitor::shared_pointer nullMonitor;
EXCEPTION_GUARD(monitorRequester->monitorConnect(errorStatus, nullMonitor,
Structure::shared_pointer()));
return nullMonitor;
return CAChannelMonitor::create(shared_from_this(), monitorRequester, pvRequest);
}
@@ -1113,3 +1109,162 @@ void CAChannelPut::unlock()
{
// TODO
}
Monitor::shared_pointer CAChannelMonitor::create(
CAChannel::shared_pointer const & channel,
epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
Monitor::shared_pointer thisPtr(new CAChannelMonitor(channel, monitorRequester, pvRequest));
static_cast<CAChannelMonitor*>(thisPtr.get())->activate();
return thisPtr;
}
CAChannelMonitor::~CAChannelMonitor()
{
// TODO
}
CAChannelMonitor::CAChannelMonitor(CAChannel::shared_pointer const & _channel,
epics::pvData::MonitorRequester::shared_pointer const & _monitorRequester,
epics::pvData::PVStructure::shared_pointer const & pvRequest) :
channel(_channel),
monitorRequester(_monitorRequester),
getType(getDBRType(pvRequest, _channel->getNativeType())),
pvStructure(createPVStructure(_channel, getType)),
changedBitSet(new BitSet(pvStructure->getStructure()->getNumberFields())),
overrunBitSet(new BitSet(pvStructure->getStructure()->getNumberFields())),
count(0),
element(new MonitorElement())
{
// TODO
changedBitSet->set(0);
element->pvStructurePtr = pvStructure;
element->changedBitSet = changedBitSet;
element->overrunBitSet = overrunBitSet;
}
void CAChannelMonitor::activate()
{
// TODO remove
thisPointer = shared_from_this();
EXCEPTION_GUARD(monitorRequester->monitorConnect(Status::Ok, shared_from_this(),
pvStructure->getStructure()));
}
/* --------------- epics::pvData::Monitor --------------- */
static void ca_subscription_handler(struct event_handler_args args)
{
CAChannelMonitor *channelMonitor = static_cast<CAChannelMonitor*>(args.usr);
channelMonitor->subscriptionEvent(args);
}
void CAChannelMonitor::subscriptionEvent(struct event_handler_args &args)
{
if (args.status == ECA_NORMAL)
{
// TODO override indicator
copyDBRtoPVStructure copyFunc = copyFuncTable[getType];
if (copyFunc)
copyFunc(args.dbr, args.count, pvStructure);
else
{
// TODO remove
std::cout << "no copy func implemented" << std::endl;
}
{
Lock lock(mutex);
count = 1;
}
monitorRequester->monitorEvent(shared_from_this());
}
else
{
//Status errorStatus(Status::STATUSTYPE_ERROR, String(ca_message(args.status)));
//EXCEPTION_GUARD(channelMonitorRequester->MonitorDone(errorStatus));
}
}
epics::pvData::Status CAChannelMonitor::start()
{
// TODO DBE_PROPERTY support
int result = ca_create_subscription(getType, channel->getElementCount(),
channel->getChannelID(), DBE_VALUE,
ca_subscription_handler, this,
&eventID);
if (result == ECA_NORMAL)
{
ca_flush_io();
return Status::Ok;
}
else
{
return Status(Status::STATUSTYPE_ERROR, String(ca_message(result)));
}
}
epics::pvData::Status CAChannelMonitor::stop()
{
int result = ca_clear_subscription(eventID);
if (result == ECA_NORMAL)
{
return Status::Ok;
}
else
{
return Status(Status::STATUSTYPE_ERROR, String(ca_message(result)));
}
}
epics::pvData::MonitorElementPtr CAChannelMonitor::poll()
{
Lock lock(mutex);
if (count)
{
count--;
return element;
}
else
{
return nullElement;
}
}
void CAChannelMonitor::release(epics::pvData::MonitorElementPtr const & /*monitorElement*/)
{
// noop
}
/* --------------- epics::pvData::Destroyable --------------- */
void CAChannelMonitor::destroy()
{
// TODO
}
+55
View File
@@ -206,6 +206,61 @@ private:
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();
// TODO weak_ptr usage?
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 */