From 5af10bb7b6ed48f37d126273811085ce02ad1003 Mon Sep 17 00:00:00 2001 From: Gasper Jansa Date: Fri, 18 Feb 2011 17:37:09 +0100 Subject: [PATCH] BaseChannelRequester --- pvAccessApp/server/baseChannelRequester.cpp | 151 ++++++++++++++++++++ pvAccessApp/server/baseChannelRequester.h | 86 +++++++++++ 2 files changed, 237 insertions(+) create mode 100644 pvAccessApp/server/baseChannelRequester.cpp create mode 100644 pvAccessApp/server/baseChannelRequester.h diff --git a/pvAccessApp/server/baseChannelRequester.cpp b/pvAccessApp/server/baseChannelRequester.cpp new file mode 100644 index 0000000..a602803 --- /dev/null +++ b/pvAccessApp/server/baseChannelRequester.cpp @@ -0,0 +1,151 @@ +/* + * baseChannelRequester.cpp + */ + +#include "baseChannelRequester.h" + +using namespace epics::pvData; + +namespace epics { namespace pvAccess { + +const Status BaseChannelRequester::okStatus = Status(); +const Status BaseChannelRequester::badCIDStatus = Status(Status::STATUSTYPE_ERROR, "bad channel id"); +const Status BaseChannelRequester::badIOIDStatus = Status(Status::STATUSTYPE_ERROR, "bad request id"); +const Status BaseChannelRequester::noReadACLStatus = Status(Status::STATUSTYPE_ERROR, "no read access"); +const Status BaseChannelRequester::noWriteACLStatus = Status(Status::STATUSTYPE_ERROR, "no write access"); +const Status BaseChannelRequester::noProcessACLStatus = Status(Status::STATUSTYPE_ERROR, "no process access"); +const Status BaseChannelRequester::otherRequestPendingStatus = Status(Status::STATUSTYPE_ERROR, "other request pending"); + +const int32 BaseChannelRequester::NULL_REQUEST = -1; + +BaseChannelRequester::BaseChannelRequester(ServerContextImpl* context, ServerChannelImpl* channel,const pvAccessID ioid, Transport* transport) : + _ioid(ioid), + _transport(transport), + _channel(channel), + _context(context), + _pendingRequest(BaseChannelRequester::NULL_REQUEST) +{ + +} + +boolean BaseChannelRequester::startRequest(int32 qos) +{ + Lock guard(_mutex); + if (_pendingRequest != NULL_REQUEST) + { + return false; + } + + _pendingRequest = qos; + return true; +} + +void BaseChannelRequester::stopRequest() +{ + Lock guard(_mutex); + _pendingRequest = NULL_REQUEST; +} + +int32 BaseChannelRequester::getPendingRequest() +{ + Lock guard(_mutex); + return _pendingRequest; +} + +String BaseChannelRequester::getRequesterName() +{ + stringstream name; + name << typeid(*_transport).name() << "/" << _ioid; + return name.str(); +} + +void BaseChannelRequester::message(const String& message, const epics::pvData::MessageType messageType) +{ + BaseChannelRequester::message(_transport, _ioid, message, messageType); +} + +void BaseChannelRequester::message(Transport* transport, const pvAccessID ioid, const String& message, const MessageType messageType) +{ + transport->enqueueSendRequest( new BaseChannelRequesterMessageTransportSender(ioid, message, messageType)); +} + +void BaseChannelRequester::sendFailureMessage(const int8 command, Transport* transport, const pvAccessID ioid, const int8 qos, const Status status) +{ + transport->enqueueSendRequest( new BaseChannelRequesterFailureMessageTransportSender(command, transport, ioid, qos, status)); +} + +BaseChannelRequesterMessageTransportSender::BaseChannelRequesterMessageTransportSender(const pvAccessID ioid, const String message,const epics::pvData::MessageType messageType): + _ioid(ioid), + _message(message), + _messageType(messageType) +{ +} + +void BaseChannelRequesterMessageTransportSender::send(ByteBuffer* buffer, TransportSendControl* control) +{ + control->startMessage((int8)18, sizeof(int32)/sizeof(int8) + 1); + buffer->putInt(_ioid); + buffer->putByte((int8)_messageType); + epics::pvData::SerializeHelper::serializeString(_message, buffer, control); +} + +void BaseChannelRequesterMessageTransportSender::lock() +{ + // noop +} + +void BaseChannelRequesterMessageTransportSender::unlock() +{ + // noop +} + +void BaseChannelRequesterMessageTransportSender::release() +{ + delete this; +} + +void BaseChannelRequesterMessageTransportSender::acquire() +{ + // noop +} + +BaseChannelRequesterFailureMessageTransportSender::BaseChannelRequesterFailureMessageTransportSender(const int8 command, + Transport* transport, const pvAccessID ioid, const int8 qos, const Status status) : + _command(command), + _ioid(ioid), + _qos(qos), + _status(status), + _transport(transport) +{ +} + +void BaseChannelRequesterFailureMessageTransportSender::send(ByteBuffer* buffer, TransportSendControl* control) +{ + control->startMessage(_command, sizeof(int32)/sizeof(int8) + 1); + buffer->putInt(_ioid); + buffer->put(_qos); + _transport->getIntrospectionRegistry()->serializeStatus(buffer, control, _status); +} + +void BaseChannelRequesterFailureMessageTransportSender::lock() +{ + // noop +} + +void BaseChannelRequesterFailureMessageTransportSender::unlock() +{ + // noop +} + +void BaseChannelRequesterFailureMessageTransportSender::release() +{ + delete this; +} + +void BaseChannelRequesterFailureMessageTransportSender::acquire() +{ + // noop +} + +} +} diff --git a/pvAccessApp/server/baseChannelRequester.h b/pvAccessApp/server/baseChannelRequester.h new file mode 100644 index 0000000..36eefa6 --- /dev/null +++ b/pvAccessApp/server/baseChannelRequester.h @@ -0,0 +1,86 @@ +/* + * baseChannelRequester.h + */ + +#ifndef BASECHANNELREQUESTER_H_ +#define BASECHANNELREQUESTER_H_ + +#include "serverContext.h" +#include "serverChannelImpl.h" + +#include +#include + +namespace epics { +namespace pvAccess { + +class BaseChannelRequester : public epics::pvData::Requester, public epics::pvData::Destroyable +{ +public: + BaseChannelRequester(ServerContextImpl* context, ServerChannelImpl* channel,const pvAccessID ioid, Transport* transport); + ~BaseChannelRequester() {}; + + boolean startRequest(int32 qos); + void stopRequest(); + int32 getPendingRequest(); + String getRequesterName(); + void message(const String& message, const epics::pvData::MessageType messageType); + static void message(Transport* transport, const pvAccessID ioid, const String& message, const epics::pvData::MessageType messageType); + static void sendFailureMessage(const int8 command, Transport* transport, const pvAccessID ioid, const int8 qos, const Status status); + + static const Status okStatus; + static const Status badCIDStatus; + static const Status badIOIDStatus; + static const Status noReadACLStatus; + static const Status noWriteACLStatus; + static const Status noProcessACLStatus; + static const Status otherRequestPendingStatus; +protected: + const pvAccessID _ioid; + Transport* _transport; + ServerChannelImpl* _channel; +private: + ServerContextImpl* _context; + static const int32 NULL_REQUEST; + int32 _pendingRequest; + epics::pvData::Mutex _mutex; +}; + +class BaseChannelRequesterMessageTransportSender : public TransportSender +{ +public: + BaseChannelRequesterMessageTransportSender(const pvAccessID _ioid, const String message,const epics::pvData::MessageType messageType); + void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + void lock(); + void unlock(); + void release(); + void acquire(); +private: + const pvAccessID _ioid; + const String _message; + const epics::pvData::MessageType _messageType; +}; + +class BaseChannelRequesterFailureMessageTransportSender : public TransportSender +{ +public: + BaseChannelRequesterFailureMessageTransportSender(const int8 command, Transport* transport, const pvAccessID ioid, const int8 qos, const Status status); + void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + void lock(); + void unlock(); + void release(); + void acquire(); + +private: + const int8 _command; + const pvAccessID _ioid; + const int8 _qos; + const Status _status; + Transport* _transport; +}; + +} +} + + +#endif /* BASECHANNELREQUESTER_H_ */