This is Unofficial EPICS BASE Doxygen Site
epics::pvAccess::ServerChannelRequesterImpl Class Reference

#include "responseHandlers.h"

+ Inheritance diagram for epics::pvAccess::ServerChannelRequesterImpl:
+ Collaboration diagram for epics::pvAccess::ServerChannelRequesterImpl:

Public Types

typedef std::tr1::shared_ptr< ServerChannelRequesterImplshared_pointer
 
typedef std::tr1::shared_ptr< const ServerChannelRequesterImplconst_shared_pointer
 
- Public Types inherited from epics::pvAccess::ChannelRequester
typedef Channel operation_type
 

Public Member Functions

virtual ~ServerChannelRequesterImpl ()
 
virtual void channelCreated (const epics::pvData::Status &status, Channel::shared_pointer const &channel) OVERRIDE FINAL
 
virtual void channelStateChange (Channel::shared_pointer const &c, const Channel::ConnectionState isConnected) OVERRIDE FINAL
 
virtual std::tr1::shared_ptr< const PeerInfogetPeerInfo () OVERRIDE FINAL
 Return information on connected peer if applicable. More...
 
virtual std::string getRequesterName () OVERRIDE FINAL
 
virtual void message (std::string const &message, epics::pvData::MessageType messageType) OVERRIDE FINAL
 
virtual void send (epics::pvData::ByteBuffer *buffer, TransportSendControl *control) OVERRIDE FINAL
 
- Public Member Functions inherited from epics::pvAccess::ChannelRequester
 POINTER_DEFINITIONS (ChannelRequester)
 
 ChannelRequester ()
 
virtual ~ChannelRequester ()
 
- Public Member Functions inherited from epics::pvAccess::Requester
 POINTER_DEFINITIONS (Requester)
 
virtual ~Requester ()
 
virtual void message (std::string const &message, MessageType messageType=errorMessage)
 
- Public Member Functions inherited from epics::pvAccess::TransportSender
 POINTER_DEFINITIONS (TransportSender)
 
 TransportSender ()
 
virtual ~TransportSender ()
 
- Public Member Functions inherited from epics::pvAccess::Lockable
 POINTER_DEFINITIONS (Lockable)
 
virtual ~Lockable ()
 
virtual void lock ()
 
virtual void unlock ()
 
- Public Member Functions inherited from epics::pvAccess::fair_queue< T >::entry
 entry ()
 
 ~entry ()
 

Static Public Member Functions

static ChannelRequester::shared_pointer create (ChannelProvider::shared_pointer const &provider, Transport::shared_pointer const &transport, const std::string channelName, const pvAccessID cid)
 

Protected Member Functions

 ServerChannelRequesterImpl (Transport::shared_pointer const &transport, const std::string channelName, const pvAccessID cid)
 

Friends

class ServerCreateChannelHandler
 

Additional Inherited Members

- Public Attributes inherited from epics::pvAccess::TransportSender
size_t bytesTX
 
size_t bytesRX
 
- Static Public Attributes inherited from epics::pvAccess::ChannelRequester
static size_t num_instances
 

Detailed Description

Definition at line 199 of file responseHandlers.h.

Member Typedef Documentation

Constructor & Destructor Documentation

epics::pvAccess::ServerChannelRequesterImpl::ServerChannelRequesterImpl ( Transport::shared_pointer const &  transport,
const std::string  channelName,
const pvAccessID  cid 
)
protected

Definition at line 791 of file responseHandlers.cpp.

792  :
793  _serverChannel(),
794  _transport(std::tr1::static_pointer_cast<detail::BlockingServerTCPTransportCodec>(transport)),
795  _channelName(channelName),
796  _cid(cid),
797  _created(false)
798 {
799 }
virtual epics::pvAccess::ServerChannelRequesterImpl::~ServerChannelRequesterImpl ( )
inlinevirtual

Definition at line 213 of file responseHandlers.h.

213 {}

Member Function Documentation

void epics::pvAccess::ServerChannelRequesterImpl::channelCreated ( const epics::pvData::Status status,
Channel::shared_pointer const &  channel 
)
virtual

The request made with ChannelProvider::createChannel() is satisfied.

Will be called at most once for each call to createChannel().

The Channel passed here must be the same as was returned by createChannel(), if it has returned. Note that this method may be called before createChanel() returns.

Status::isOk() indicates that the Channel is valid. Calls to Channel methods can be made from this method, and later until Channel::destroy() is called.

!Status::isOk() indicates that the Channel is not available. No calls to the Channel are permitted. channelStateChange() will never be called.

Caller must hold no locks.

Parameters
statusCompletion status.
channelThe channel.

Implements epics::pvAccess::ChannelRequester.

Definition at line 813 of file responseHandlers.cpp.

814 {
815  if(_created)
816  throw std::logic_error("Channel already created");
817  if(detail::BlockingServerTCPTransportCodec::shared_pointer transport = _transport.lock())
818  {
819  ServerChannel::shared_pointer serverChannel;
820  try
821  {
822  if (status.isSuccess())
823  {
824  //
825  // create a new channel instance
826  //
827  pvAccessID sid = transport->preallocateChannelSID();
828  try
829  {
830  serverChannel.reset(new ServerChannel(channel, shared_from_this(), _cid, sid));
831 
832  // ack allocation and register
833  transport->registerChannel(sid, serverChannel);
834 
835  } catch (...)
836  {
837  // depreallocate and rethrow
838  transport->depreallocateChannelSID(sid);
839  throw;
840  }
841  }
842 
843 
844  {
845  Lock guard(_mutex);
846  _status = status;
847  _serverChannel = serverChannel;
848  _created = true;
849  }
850 
851  TransportSender::shared_pointer thisSender = shared_from_this();
852  transport->enqueueSendRequest(thisSender);
853  }
854  catch (std::exception& e)
855  {
856  LOG(logLevelDebug, "Exception caught when creating channel '%s': %s", _channelName.c_str(), e.what());
857  {
858  Lock guard(_mutex);
859  _status = Status(Status::STATUSTYPE_FATAL, "failed to create channel", e.what());
860  }
861  TransportSender::shared_pointer thisSender = shared_from_this();
862  transport->enqueueSendRequest(thisSender);
863  }
864  catch (...)
865  {
866  LOG(logLevelDebug, "Exception caught when creating channel: %s", _channelName.c_str());
867  {
868  Lock guard(_mutex);
869  _status = Status(Status::STATUSTYPE_FATAL, "failed to create channel");
870  }
871  TransportSender::shared_pointer thisSender = shared_from_this();
872  transport->enqueueSendRequest(thisSender);
873  }
874  }
875 }
epicsInt32 pvAccessID
Definition: pvaDefs.h:18
pvd::Status status
A lock for multithreading.
Definition: lock.h:36
#define LOG(level, format,...)
Definition: logger.h:48
bool isSuccess() const
Definition: status.h:103
void epics::pvAccess::ServerChannelRequesterImpl::channelStateChange ( Channel::shared_pointer const &  channel,
const Channel::ConnectionState  connectionState 
)
virtual

Called occasionally after channelCreated() with Status::isOk() to give notification of connection state changes.

Caller must hold no locks.

Parameters
cThe channel.
connectionStateThe new connection state.

Implements epics::pvAccess::ChannelRequester.

Definition at line 877 of file responseHandlers.cpp.

878 {
879  if(isConnected==Channel::CONNECTED || isConnected==Channel::NEVER_CONNECTED)
880  return;
881 
882  if(detail::BlockingServerTCPTransportCodec::shared_pointer transport = _transport.lock())
883  {
884  ServerChannel::shared_pointer channel;
885  {
886  Lock guard(_mutex);
887  _created = false;
888  channel= dynamic_pointer_cast<ServerChannel>(_serverChannel.lock());
889  }
890 
891  if (!channel)
892  return;
893 
894  // destroy
895  channel->destroy();
896 
897  // .. and unregister
898  transport->unregisterChannel(channel->getSID());
899 
900  // send response back
901  TransportSender::shared_pointer sr(new ServerDestroyChannelHandlerTransportSender(channel->getCID(), channel->getSID()));
902  transport->enqueueSendRequest(sr);
903  }
904 }
A lock for multithreading.
Definition: lock.h:36
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:808
ChannelRequester::shared_pointer epics::pvAccess::ServerChannelRequesterImpl::create ( ChannelProvider::shared_pointer const &  provider,
Transport::shared_pointer const &  transport,
const std::string  channelName,
const pvAccessID  cid 
)
static

Definition at line 801 of file responseHandlers.cpp.

804 {
805  // TODO use std::make_shared
806  std::tr1::shared_ptr<ServerChannelRequesterImpl> tp(new ServerChannelRequesterImpl(transport, channelName, cid));
807  ChannelRequester::shared_pointer cr = tp;
808  // TODO exception guard and report error back
809  provider->createChannel(channelName, cr, transport->getPriority());
810  return cr;
811 }
ServerChannelRequesterImpl(Transport::shared_pointer const &transport, const std::string channelName, const pvAccessID cid)
std::tr1::shared_ptr< const PeerInfo > epics::pvAccess::ServerChannelRequesterImpl::getPeerInfo ( )
virtual

Return information on connected peer if applicable.

A server-type ChannelProvider will use this method to discover if a remote client has provided credentials which may be used in access control decisions.

Default implementation returns NULL.

isConnected()==true and getPeerInfo()==NULL when the ChannelProvider does not provide information about the peer. This should be treated as an unauthenticated, anonymous, peer.

The returned instance must not change, and a different instance should be returned if/when peer information changes (eg. after reconnect).

May return !NULL when !isConnected(). getPeerInfo() must be called before testing isConnected() in situations where connection state is being polled.

Reimplemented from epics::pvAccess::ChannelRequester.

Definition at line 906 of file responseHandlers.cpp.

907 {
908  if(detail::BlockingServerTCPTransportCodec::shared_pointer transport = _transport.lock()) {
909  epicsGuard<epicsMutex> G(transport->_mutex);
910  return transport->_peerInfo;
911 
912  } else {
913  return std::tr1::shared_ptr<const PeerInfo>();
914  }
915 }
string epics::pvAccess::ServerChannelRequesterImpl::getRequesterName ( )
virtual

The requester must have a name.

Returns
The requester's name.

Implements epics::pvAccess::Requester.

Definition at line 917 of file responseHandlers.cpp.

918 {
919  detail::BlockingServerTCPTransportCodec::shared_pointer transport = _transport.lock();
920  if (transport)
921  return transport->getRemoteName();
922  else
923  return "<unknown>:0";
924 }
void epics::pvAccess::ServerChannelRequesterImpl::message ( std::string const &  message,
epics::pvData::MessageType  messageType 
)
virtual

Definition at line 926 of file responseHandlers.cpp.

927 {
928  LOG(logLevelDebug, "[%s] %s", getMessageTypeName(messageType).c_str(), message.c_str());
929 }
epicsShareExtern std::string getMessageTypeName(MessageType messageType)
Definition: requester.cpp:25
#define LOG(level, format,...)
Definition: logger.h:48
virtual void message(std::string const &message, epics::pvData::MessageType messageType) OVERRIDE FINAL
void epics::pvAccess::ServerChannelRequesterImpl::send ( epics::pvData::ByteBuffer buffer,
TransportSendControl control 
)
virtual

Called by transport. By this call transport gives callee ownership over the buffer. Calls on TransportSendControl instance must be made from calling thread. Moreover, ownership is valid only for the time of call of this method. NOTE: these limitations allow efficient implementation.

Implements epics::pvAccess::TransportSender.

Definition at line 931 of file responseHandlers.cpp.

932 {
933  ServerChannel::shared_pointer serverChannel;
934  Status status;
935  {
936  Lock guard(_mutex);
937  serverChannel = _serverChannel.lock();
938  status = _status;
939  }
940 
941  if (detail::BlockingServerTCPTransportCodec::shared_pointer transport = _transport.lock())
942  {
943  // error response
944  if (!serverChannel)
945  {
946  control->startMessage((int8)CMD_CREATE_CHANNEL, 2*sizeof(int32)/sizeof(int8));
947  buffer->putInt(_cid);
948  buffer->putInt(-1);
949  // error status is expected or channel has been destroyed locally
950  if (status.isSuccess())
951  status = Status(Status::STATUSTYPE_ERROR, "channel has been destroyed");
952  status.serialize(buffer, control);
953  }
954  // OK
955  else
956  {
957  ServerChannel::shared_pointer serverChannelImpl = dynamic_pointer_cast<ServerChannel>(serverChannel);
958  control->startMessage((int8)CMD_CREATE_CHANNEL, 2*sizeof(int32)/sizeof(int8));
959  buffer->putInt(serverChannelImpl->getCID());
960  buffer->putInt(serverChannelImpl->getSID());
961  status.serialize(buffer, control);
962  }
963  }
964 }
int8_t int8
Definition: pvType.h:75
pvd::Status status
EPICS_ALWAYS_INLINE void putInt(int32 value)
Definition: byteBuffer.h:537
A lock for multithreading.
Definition: lock.h:36
void serialize(ByteBuffer *buffer, SerializableControl *flusher) const
Definition: status.cpp:45
bool isSuccess() const
Definition: status.h:103
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:808
virtual void startMessage(epics::pvData::int8 command, std::size_t ensureCapacity, epics::pvData::int32 payloadSize=0)=0
int32_t int32
Definition: pvType.h:83

Friends And Related Function Documentation

friend class ServerCreateChannelHandler
friend

Definition at line 204 of file responseHandlers.h.


The documentation for this class was generated from the following files: