Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes

TAO_Connection_Handler Class Reference

TAO_Connection_Handler. More...

#include <Connection_Handler.h>

Inheritance diagram for TAO_Connection_Handler:
Inheritance graph
[legend]
Collaboration diagram for TAO_Connection_Handler:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 TAO_Connection_Handler (void)
 Constructor.
 TAO_Connection_Handler (TAO_ORB_Core *orb_core)
 Constructor.
virtual ~TAO_Connection_Handler (void)
 Destructor.
TAO_Transporttransport (void)
 Return the underlying transport object.
void transport (TAO_Transport *transport)
 Set the underlying transport object.
bool is_closed (void) const
 Is the handler closed or timed out?
bool is_open (void) const
 Is the handler open?
bool is_timeout (void) const
 Closed due to timeout?
bool is_connecting (void) const
 Is the handler in the process of being connected?
virtual int close_connection (void)=0
 Close the underlying connection.
virtual int handle_input (ACE_HANDLE fd)=0
int svc_i (void)
virtual int open_handler (void *)=0
 A open () hook.
virtual int close_handler (u_long flags=0)
void connection_pending (void)
void cancel_pending_connection (void)
virtual int set_dscp_codepoint (CORBA::Boolean set_network_priority)
virtual int set_dscp_codepoint (CORBA::Long dscp_codepoint)
virtual int release_os_resources (void)
 Release the OS resources related to this handler.
virtual int handle_write_ready (const ACE_Time_Value *timeout)

Protected Member Functions

TAO_ORB_Coreorb_core (void)
 Return our TAO_ORB_Core pointer.
int shared_open (void)
int set_socket_option (ACE_SOCK &sock, int snd_size, int rcv_size)
 Set options on the socket.
Helper methods for Event_Handler-based derived classes.

Many (actually all so far) implementations of TAO_Connection_Handler are a mixin of TAO_Connection_Handler and some form of ACE_Event_Handler. The following methods simplify such implementations by capturing the common code in a single place.

int handle_output_eh (ACE_HANDLE h, ACE_Event_Handler *eh)
 Implement the handle_output() callback.
int handle_input_eh (ACE_HANDLE h, ACE_Event_Handler *eh)
 Implement the handle_input() callback.
int handle_input_internal (ACE_HANDLE h, ACE_Event_Handler *eh)
 Implement the handle_output() callback.
int close_connection_eh (ACE_Event_Handler *eh)
virtual void pre_io_hook (int &return_value)
virtual void pos_io_hook (int &return_value)

Private Member Functions

void operator= (const TAO_Connection_Handler &)
 TAO_Connection_Handler (const TAO_Connection_Handler &)

Private Attributes

TAO_ORB_Core *const orb_core_
 Pointer to the TAO_ORB_Core.
TAO_Transporttransport_
 Transport object reference.
bool connection_pending_
 Stores the connection pending state.
bool is_closed_

Detailed Description

TAO_Connection_Handler.

This class is an abstraction for the connection handlers. The connections handler in every protocol can derive from this class as well as the ACE_Svc_Handler specialised for the right protocol. This way, most of the common code for the different protocols would be in this implementation.

Definition at line 56 of file Connection_Handler.h.


Constructor & Destructor Documentation

TAO_Connection_Handler::TAO_Connection_Handler ( void   ) 

Constructor.

TAO_Connection_Handler::TAO_Connection_Handler ( TAO_ORB_Core orb_core  ) 

Constructor.

Definition at line 27 of file Connection_Handler.cpp.

  : orb_core_ (orb_core),
    transport_ (0),
    connection_pending_ (false),
    is_closed_ (false)
{
  // Put ourselves in the connection wait state as soon as we get
  // created
  this->state_changed (TAO_LF_Event::LFS_CONNECTION_WAIT,
                       this->orb_core_->leader_follower ());
}

TAO_Connection_Handler::~TAO_Connection_Handler ( void   )  [virtual]

Destructor.

Definition at line 39 of file Connection_Handler.cpp.

{
  //@@ CONNECTION_HANDLER_DESTRUCTOR_ADD_HOOK
}

TAO_Connection_Handler::TAO_Connection_Handler ( const TAO_Connection_Handler  )  [private]

Member Function Documentation

void TAO_Connection_Handler::cancel_pending_connection ( void   ) 

A pending connection may be canceled due to an error detected while the initiating thread is still in the Connector.

Definition at line 58 of file Connection_Handler.inl.

{
  if (this->connection_pending_)
    {
      this->connection_pending_ = false;
      this->transport()->remove_reference();
    }
}

virtual int TAO_Connection_Handler::close_connection ( void   )  [pure virtual]

Close the underlying connection.

Used by the ORB to actively close connections that are idle, stale or somehow are determined to be broken before the Reactor does.

Returns:
Return 0 if the connection was already closed, non-zero otherwise.

Implemented in TAO_IIOP_Connection_Handler, TAO_DIOP_Connection_Handler, and TAO_UIOP_Connection_Handler.

int TAO_Connection_Handler::close_connection_eh ( ACE_Event_Handler eh  )  [protected]

Implement close_connection() for Connection_Handlers that are also Event_Handlers.

Definition at line 297 of file Connection_Handler.cpp.

{

  this->is_closed_ = true;

  // Save the ID for debugging messages
  ACE_HANDLE const handle = eh->get_handle ();

  size_t const id = this->transport ()->id ();
  if (TAO_debug_level)
    {
      ACE_DEBUG  ((LM_DEBUG,
                   "TAO (%P|%t) - Connection_Handler[%d]::"
                   "close_connection_eh, purging entry from cache\n",
                   handle));
    }

  this->transport ()->pre_close ();

  // @@ This seems silly, but if we have no reason to be in the
  // reactor, then we dont remove ourselves.
  if (this->transport ()->wait_strategy ()->is_registered ())
    {
      ACE_Reactor *eh_reactor = eh->reactor ();

      if (this->orb_core_->has_shutdown () == 0)
        {
          // If the ORB is nil, get the reactor from orb_core which gets it
          // from LF.
          if (eh_reactor == 0)
            eh_reactor = this->transport()->orb_core()->reactor ();
        }

      // The Reactor must not be null, otherwise something else is
      // horribly broken.
      ACE_ASSERT (eh_reactor != 0);

      if (TAO_debug_level)
        {
          ACE_DEBUG  ((LM_DEBUG,
                       "TAO (%P|%t) - Connection_Handler[%d]::"
                       "close_connection_eh, removing from the reactor\n",
                       handle));
        }

      // Use id instead of handle. Why? "handle" may be invalid for RW
      // cases  when drop_reply_on_shutdown is on, and when the
      // orb_core is shutting down. This means that the handler will
      // be left behind in the reactor which would create problems
      // later. Just forcefully remove them. If none exists reactor
      // will make things safer.
      ACE_HANDLE tmp_handle = handle;
      if (this->orb_core_->has_shutdown ())
        tmp_handle = (ACE_HANDLE) id;

      eh_reactor->remove_handler (tmp_handle,
                                  ACE_Event_Handler::ALL_EVENTS_MASK |
                                  ACE_Event_Handler::DONT_CALL);

      // Also cancel any timers, we may create those for time-limited
      // buffering
      if (TAO_debug_level)
        {
          ACE_DEBUG  ((LM_DEBUG,
                       "TAO (%P|%t) - Connection_Handler[%d]::"
                       "close_connection_eh, cancel all timers\n",
                       handle));
        }

      eh_reactor->cancel_timer (eh);

      // @@ This seems silly, the reactor is a much better authority to
      //    find out if a handle is registered...
      this->transport ()->wait_strategy ()->is_registered (false);
    }

  // This call should be made only after the cache and reactor are
  // cleaned up. This call can make upcalls to the application which
  // in turn can make remote calls (Bug 1551 and Bug 1482). The remote
  // calls from the application can try to use this handler from the
  // cache or from the reactor. So clean them up before this is
  // called.
  this->transport ()->send_connection_closed_notifications ();
  this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED,
                       this->orb_core_->leader_follower ());

  if (TAO_debug_level)
    {
      ACE_DEBUG  ((LM_DEBUG,
                   "TAO (%P|%t) - Connection_Handler[%d]::"
                   "close_connection_eh\n",
                   id));
    }

  return 1;
}

int TAO_Connection_Handler::close_handler ( u_long  flags = 0  )  [virtual]

A close() hook, called by the Transport Connector when they want to close this handler

Definition at line 434 of file Connection_Handler.cpp.

{
  this->is_closed_ = true;
  this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED,
                       this->orb_core_->leader_follower ());

  // If there was a pending connection cancel it.
  this->cancel_pending_connection ();

  // Purge transport from cache if it's in cache.
  this->transport ()->purge_entry();

  return 0;
}

void TAO_Connection_Handler::connection_pending ( void   ) 

When waiting for an asynchronous connection to complete an additional reference must be maintained, related to bugzilla #2417. However once the connection is successfully established, this reference must be removed. Using connection_pending allows the connection handler to know that it is opening as a result of a delayed asynch connection rather than an immediate synch connection, which has no additional reference needs.

Definition at line 48 of file Connection_Handler.inl.

{
  if (!this->connection_pending_)
    {
      this->connection_pending_ = true;
      this->transport()->add_reference();
    }
}

virtual int TAO_Connection_Handler::handle_input ( ACE_HANDLE  fd  )  [pure virtual]

The event handler calls, here so that other objects who hold a reference to this object can call the event handler methods.

Implemented in TAO_IIOP_Connection_Handler, TAO_DIOP_Connection_Handler, and TAO_UIOP_Connection_Handler.

int TAO_Connection_Handler::handle_input_eh ( ACE_HANDLE  h,
ACE_Event_Handler eh 
) [protected]

Implement the handle_input() callback.

Definition at line 219 of file Connection_Handler.cpp.

{
  // If we can't process upcalls just return
  if (!this->transport ()->wait_strategy ()->can_process_upcalls ())
    {
      if (TAO_debug_level > 6)
        ACE_DEBUG ((LM_DEBUG,
                    "TAO (%P|%t) - Connection_Handler[%d]::handle_input_eh, "
                    "not going to handle_input on transport "
                    "because upcalls temporarily suspended on this thread\n",
                    this->transport()->id()));
      return 0;
    }

  int const result = this->handle_input_internal (h, eh);

  if (result == -1)
    {
      this->close_connection ();
      return 0;
    }

  return result;
}

int TAO_Connection_Handler::handle_input_internal ( ACE_HANDLE  h,
ACE_Event_Handler eh 
) [protected]

Implement the handle_output() callback.

Definition at line 245 of file Connection_Handler.cpp.

{
  // Let the transport know that it is used
  (void) this->transport ()->update_transport ();

  // Grab the transport id now and use the cached value for printing
  // since the  transport could dissappear by the time the thread
  // returns.
  size_t const t_id = this->transport ()->id ();

  if (TAO_debug_level > 6)
    {
      ACE_HANDLE handle = eh->get_handle();
      ACE_DEBUG ((LM_DEBUG,
                  "TAO (%P|%t) - Connection_Handler[%d]::handle_input, "
                  "handle = %d/%d\n",
                  t_id, handle, h));
    }

  TAO_Resume_Handle resume_handle (this->orb_core (), eh->get_handle ());

  int return_value = 0;

  this->pre_io_hook (return_value);

  if (return_value != 0)
    return return_value;

  return_value = this->transport ()->handle_input (resume_handle);

  this->pos_io_hook (return_value);

  // Bug 1647; might need to change resume_handle's flag or
  // change handle_input return value.
  resume_handle.handle_input_return_value_hook(return_value);

  if (TAO_debug_level > 6)
    {
      ACE_HANDLE handle = eh->get_handle ();
      ACE_DEBUG ((LM_DEBUG,
                  "TAO (%P|%t) - Connection_Handler[%d]::handle_input, "
                  "handle = %d/%d, retval = %d\n",
                  t_id, handle, h, return_value));
    }

  if (return_value == -1)
    resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
  return return_value;
}

int TAO_Connection_Handler::handle_output_eh ( ACE_HANDLE  h,
ACE_Event_Handler eh 
) [protected]

Implement the handle_output() callback.

Definition at line 182 of file Connection_Handler.cpp.

{
  // Let the transport that it is going to be used
  (void) this->transport ()->update_transport ();

  // Instantiate the resume handle here.. This will automatically
  // resume the handle once data is written..
  TAO_Resume_Handle resume_handle (this->orb_core (),
                                   eh->get_handle ());

  int return_value = 0;
  this->pre_io_hook (return_value);
  if (return_value != 0)
    {
      resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
      return return_value;
    }

  // The default constraints are to never block.
  TAO::Transport::Drain_Constraints dc;
  if (this->transport ()->handle_output (dc) == TAO_Transport::DR_ERROR)
    {
      return_value = -1;
    }

  this->pos_io_hook (return_value);

  if (return_value != 0)
    {
      resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
    }

  return return_value;
}

int TAO_Connection_Handler::handle_write_ready ( const ACE_Time_Value timeout  )  [virtual]

Derived classes should implement this for proper support with the Blocking Flushing Strategy.

Reimplemented in TAO_IIOP_Connection_Handler, TAO_DIOP_Connection_Handler, and TAO_UIOP_Connection_Handler.

Definition at line 70 of file Connection_Handler.inl.

{
  return 0;
}

bool TAO_Connection_Handler::is_closed ( void   )  const

Is the handler closed or timed out?

Definition at line 22 of file Connection_Handler.inl.

bool TAO_Connection_Handler::is_connecting ( void   )  const

Is the handler in the process of being connected?

Definition at line 41 of file Connection_Handler.inl.

{
  return this->state_ == TAO_LF_Event::LFS_CONNECTION_WAIT;
}

bool TAO_Connection_Handler::is_open ( void   )  const

Is the handler open?

Definition at line 35 of file Connection_Handler.inl.

{
  return this->state_ == TAO_LF_Event::LFS_SUCCESS;
}

bool TAO_Connection_Handler::is_timeout ( void   )  const

Closed due to timeout?

Definition at line 29 of file Connection_Handler.inl.

{
  return (this->state_ == TAO_LF_Event::LFS_TIMEOUT);
}

virtual int TAO_Connection_Handler::open_handler ( void *   )  [pure virtual]

A open () hook.

See Thread_Per_Connection_Handler for a use case

Implemented in TAO_IIOP_Connection_Handler, TAO_DIOP_Connection_Handler, and TAO_UIOP_Connection_Handler.

void TAO_Connection_Handler::operator= ( const TAO_Connection_Handler  )  [private]
TAO_ORB_Core * TAO_Connection_Handler::orb_core ( void   )  [protected]

Return our TAO_ORB_Core pointer.

Definition at line 10 of file Connection_Handler.inl.

{
  return this->orb_core_;
}

void TAO_Connection_Handler::pos_io_hook ( int &  return_value  )  [protected, virtual]

Post-invocation hook for I/O operations (handle_input() & handle_output()) See the SSLIOP protocol for an interesting use-case

Definition at line 429 of file Connection_Handler.cpp.

{
}

void TAO_Connection_Handler::pre_io_hook ( int &  return_value  )  [protected, virtual]

Pre-invocation hook for I/O operations (handle_input() & handle_output()) See the SSLIOP protocol for an interesting use-case

Definition at line 424 of file Connection_Handler.cpp.

{
}

int TAO_Connection_Handler::release_os_resources ( void   )  [virtual]

Release the OS resources related to this handler.

Reimplemented in TAO_IIOP_Connection_Handler, TAO_DIOP_Connection_Handler, and TAO_UIOP_Connection_Handler.

Definition at line 416 of file Connection_Handler.cpp.

{
  return 0;
}

int TAO_Connection_Handler::set_dscp_codepoint ( CORBA::Long  dscp_codepoint  )  [virtual]

Reimplemented in TAO_IIOP_Connection_Handler, and TAO_DIOP_Connection_Handler.

Definition at line 410 of file Connection_Handler.cpp.

{
  return 0;
}

int TAO_Connection_Handler::set_dscp_codepoint ( CORBA::Boolean  set_network_priority  )  [virtual]

Set the Diff-Serv codepoint on outgoing packets. Only has effect for remote protocols (e.g., IIOP); no effect for local protocols (UIOP). Default implementation is for local protocols. Remote protocols must overwrite implementation.

Reimplemented in TAO_IIOP_Connection_Handler, and TAO_DIOP_Connection_Handler.

Definition at line 404 of file Connection_Handler.cpp.

{
  return 0;
}

int TAO_Connection_Handler::set_socket_option ( ACE_SOCK sock,
int  snd_size,
int  rcv_size 
) [protected]

Set options on the socket.

Definition at line 58 of file Connection_Handler.cpp.

{
#if !defined (ACE_LACKS_SO_SNDBUF)
  if (snd_size != 0
      && sock.set_option (SOL_SOCKET,
                          SO_SNDBUF,
                          (void *) &snd_size,
                          sizeof (snd_size)) == -1
      && errno != ENOTSUP)
  {
    return -1;
  }
#endif /* !ACE_LACKS_SO_SNDBUF */

#if !defined (ACE_LACKS_SO_RCVBUF)
  if (rcv_size != 0
      && sock.set_option (SOL_SOCKET,
                          SO_RCVBUF,
                          (void *) &rcv_size,
                          sizeof (int)) == -1
      && errno != ENOTSUP)
  {
    return -1;
  }
#endif /* !ACE_LACKS_SO_RCVBUF */

#if defined (ACE_LACKS_SO_SNDBUF) && defined (ACE_LACKS_SO_RCVBUF)
   ACE_UNUSED_ARG (snd_size);
   ACE_UNUSED_ARG (rcv_size);
#endif

  // Set the close-on-exec flag for that file descriptor. If the
  // operation fails we are out of luck (some platforms do not support
  // it and return -1).
  (void) sock.enable (ACE_CLOEXEC);

  return 0;
}

int TAO_Connection_Handler::shared_open ( void   )  [protected]

A common function called at the start of any protocol-specific open. Returns -1 on a failure (although no failure mode is currently defined).

Definition at line 45 of file Connection_Handler.cpp.

{
  // This reference counting is related to asynch connections.  It
  // should probably be managed by the ACE_Strategy_Connector, since
  // that's really the reference being managed here.  also, whether
  // open ultimately succeeds or fails, the connection attempted is
  // ending, so the reference must be removed in any case.
  this->cancel_pending_connection();

  return 0;
}

int TAO_Connection_Handler::svc_i ( void   ) 

This method is invoked from the svc () method of the Svc_Handler Object.

Definition at line 100 of file Connection_Handler.cpp.

{
  int result = 0;

  if (TAO_debug_level > 0)
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("TAO (%P|%t) - Connection_Handler::svc_i begin\n")));

  // Here we simply synthesize the "typical" event loop one might find
  // in a reactive handler, except that this can simply block waiting
  // for input.

  ACE_Time_Value *max_wait_time = 0;
  ACE_Time_Value timeout;
  ACE_Time_Value current_timeout;

  if (this->orb_core_->thread_per_connection_timeout (timeout))
    {
      current_timeout = timeout;
      max_wait_time = &current_timeout;
    }

  TAO_Resume_Handle rh (this->orb_core_,
                        ACE_INVALID_HANDLE);

  // We exit of the loop if
  // - If the ORB core is shutdown by another thread
  // - Or if the transport is null. This could happen if an error
  // occured.
  // - Or if during processing a return value of -1 is received.
  while (!this->orb_core_->has_shutdown ()
         && result >= 0)
    {
      // Let the transport know that it is used
      (void) this->transport ()->update_transport ();

      result = this->transport ()->handle_input (rh, max_wait_time);

      if (result == -1 && errno == ETIME)
        {
          // Ignore timeouts, they are only used to wake up and
          // shutdown.
          result = 0;

          // Reset errno to make sure we don't trip over an old value
          // of errno in case it is not reset when the recv() call
          // fails if the socket has been closed.
          errno = 0;
        }
      else if (result == -1)
        {
          // Something went wrong with the socket. Just quit
          return result;
        }

      current_timeout = timeout;

      if (TAO_debug_level > 0)
        ACE_DEBUG ((LM_DEBUG,
                    "TAO (%P|%t) - Connection_Handler::svc_i - "
                    "loop <%d>\n", current_timeout.msec ()));
    }

  if (TAO_debug_level > 0)
    ACE_DEBUG  ((LM_DEBUG,
                 "TAO (%P|%t) - Connection_Handler::svc_i end\n"));

  return result;
}

TAO_Transport * TAO_Connection_Handler::transport ( void   ) 

Return the underlying transport object.

Definition at line 16 of file Connection_Handler.inl.

{
  return this->transport_;
}

void TAO_Connection_Handler::transport ( TAO_Transport transport  ) 

Set the underlying transport object.

Definition at line 171 of file Connection_Handler.cpp.

{
  this->transport_ = transport;

  // Enable reference counting on the event handler.
  this->transport_->event_handler_i ()->reference_counting_policy ().value (
      ACE_Event_Handler::Reference_Counting_Policy::ENABLED
    );
}


Member Data Documentation

Stores the connection pending state.

Definition at line 214 of file Connection_Handler.h.

Once closed make sure the transport is not added back to the cache. This is distinct from the leader-follower state so it cannot be reset.

Definition at line 218 of file Connection_Handler.h.

Pointer to the TAO_ORB_Core.

Definition at line 208 of file Connection_Handler.h.

Transport object reference.

Definition at line 211 of file Connection_Handler.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines