uiop_connector.cpp

来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 482 行 · 第 1/2 页

CPP
482
字号
#include "UIOP_Connector.h"

#if TAO_HAS_UIOP == 1

#include "UIOP_Profile.h"
#include "tao/debug.h"
#include "tao/ORB_Core.h"
#include "tao/Environment.h"
#include "tao/Protocols_Hooks.h"
#include "tao/Base_Transport_Property.h"
#include "tao/Transport_Cache_Manager.h"
#include "tao/Thread_Lane_Resources.h"
#include "tao/Connect_Strategy.h"
#include "ace/OS_NS_strings.h"

ACE_RCSID(Strategies,
          UIOP_Connector,
          "UIOP_Connector.cpp,v 1.42 2003/11/04 05:21:38 dhinton Exp")

#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)

template class TAO_Connect_Concurrency_Strategy<TAO_UIOP_Connection_Handler>;
template class TAO_Connect_Creation_Strategy<TAO_UIOP_Connection_Handler>;
template class ACE_Strategy_Connector<TAO_UIOP_Connection_Handler, ACE_LSOCK_CONNECTOR>;
template class ACE_Connect_Strategy<TAO_UIOP_Connection_Handler, ACE_LSOCK_CONNECTOR>;
template class ACE_Connector_Base<TAO_UIOP_Connection_Handler>;
template class ACE_Connector<TAO_UIOP_Connection_Handler, ACE_LSOCK_CONNECTOR>;
template class ACE_NonBlocking_Connect_Handler<TAO_UIOP_Connection_Handler>;

#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)

#pragma instantiate ACE_Node<ACE_UNIX_Addr>
#pragma instantiate ACE_Unbounded_Stack<ACE_UNIX_Addr>

#pragma instantiate TAO_Connect_Concurrency_Strategy<TAO_UIOP_Connection_Handler>
#pragma instantiate TAO_Connect_Creation_Strategy<TAO_UIOP_Connection_Handler>
#pragma instantiate ACE_Strategy_Connector<TAO_UIOP_Connection_Handler, ACE_LSOCK_CONNECTOR>
#pragma instantiate ACE_Connect_Strategy<TAO_UIOP_Connection_Handler, ACE_LSOCK_CONNECTOR>
#pragma instantiate ACE_Connector_Base<TAO_UIOP_Connection_Handler>
#pragma instantiate ACE_Connector<TAO_UIOP_Connection_Handler, ACE_LSOCK_CONNECTOR>
#pragma instantiate ACE_NonBlocking_Connect_Handler<TAO_UIOP_Connection_Handler>

#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */

TAO_UIOP_Connector::TAO_UIOP_Connector (CORBA::Boolean flag)
  : TAO_Connector (TAO_TAG_UIOP_PROFILE),
    connect_strategy_ (),
    base_connector_ (),
    lite_flag_ (flag)
{
}

TAO_UIOP_Connector::~TAO_UIOP_Connector (void)
{
}

int
TAO_UIOP_Connector::open (TAO_ORB_Core *orb_core)
{
  this->orb_core (orb_core);

  // Create our connect strategy
  if (this->create_connect_strategy () == -1)
    return -1;

  if (this->init_uiop_properties () != 0)
    return -1;

  // Our connect creation strategy
  TAO_UIOP_CONNECT_CREATION_STRATEGY *connect_creation_strategy = 0;

  ACE_NEW_RETURN (connect_creation_strategy,
                  TAO_UIOP_CONNECT_CREATION_STRATEGY
                      (orb_core->thr_mgr (),
                       orb_core,
                       &(this->uiop_properties_),
                       this->lite_flag_),
                  -1);

  /// Our activation strategy
  TAO_UIOP_CONNECT_CONCURRENCY_STRATEGY *concurrency_strategy = 0;

  ACE_NEW_RETURN (concurrency_strategy,
                  TAO_UIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core),
                  -1);

  return this->base_connector_.open (this->orb_core ()->reactor (),
                                     connect_creation_strategy,
                                     &this->connect_strategy_,
                                     concurrency_strategy);
}

int
TAO_UIOP_Connector::close (void)
{
  // Zap the creation strategy that we created earlier.
  delete this->base_connector_.creation_strategy ();
  delete this->base_connector_.concurrency_strategy ();

  return this->base_connector_.close ();
}


int
TAO_UIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
{
  TAO_UIOP_Endpoint *uiop_endpoint =
    this->remote_endpoint (endpoint);

  if (uiop_endpoint == 0)
    return -1;

   const ACE_UNIX_Addr &remote_address =
     uiop_endpoint->object_addr ();

   // @@ Note, POSIX.1g renames AF_UNIX to AF_LOCAL.
   // Verify that the remote ACE_UNIX_Addr was initialized properly.
   // Failure can occur if hostname lookup failed when initializing the
   // remote ACE_INET_Addr.
   if (remote_address.get_type () != AF_UNIX)
     {
       if (TAO_debug_level > 0)
         {
           ACE_DEBUG ((LM_DEBUG,
                       ACE_LIB_TEXT ("TAO (%P|%t) UIOP failure.\n")
                       ACE_LIB_TEXT ("TAO (%P|%t) This is most likely ")
                       ACE_LIB_TEXT ("due to a hostname lookup ")
                       ACE_LIB_TEXT ("failure.\n")));
         }

       return -1;
     }

   return 0;
}

TAO_Transport *
TAO_UIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *,
                                     TAO_Transport_Descriptor_Interface &desc,
                                     ACE_Time_Value *max_wait_time)
{
  if (TAO_debug_level > 0)
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("TAO (%P|%t) Connector::connect - ")
                ACE_TEXT ("looking for UIOP connection.\n")));

  TAO_UIOP_Endpoint *uiop_endpoint =
    this->remote_endpoint (desc.endpoint ());

  if (uiop_endpoint == 0)
    return 0;

  const ACE_UNIX_Addr &remote_address =
    uiop_endpoint->object_addr ();

  if (TAO_debug_level > 2)
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("(%P|%t) UIOP_Connector::connect ")
                ACE_TEXT ("making a new connection \n")));

  // Get the right synch options
  ACE_Synch_Options synch_options;

  this->active_connect_strategy_->synch_options (max_wait_time,
                                                 synch_options);

  TAO_UIOP_Connection_Handler *svc_handler = 0;

  // Connect.
  int result =
    this->base_connector_.connect (svc_handler,
                                   remote_address,
                                   synch_options);

  // This call creates the service handler and bumps the #REFCOUNT# up
  // one extra.  There are three possibilities: (a) connection
  // succeeds immediately - in this case, the #REFCOUNT# on the
  // handler is two; (b) connection completion is pending - in this
  // case, the #REFCOUNT# on the handler is also two; (c) connection
  // fails immediately - in this case, the #REFCOUNT# on the handler
  // is one since close() gets called on the handler.
  //
  // The extra reference count in
  // TAO_Connect_Creation_Strategy::make_svc_handler() is needed in
  // the case when connection completion is pending and we are going
  // to wait on a variable in the handler to changes, signifying
  // success or failure.  Note, that this increment cannot be done
  // once the connect() returns since this might be too late if
  // another thread pick up the completion and potentially deletes the
  // handler before we get a chance to increment the reference count.

  // No immediate result.  Wait for completion.
  if (result == -1 && errno == EWOULDBLOCK)
    {
      if (TAO_debug_level > 2)
        ACE_DEBUG ((LM_DEBUG,
                    "TAO (%P|%t) - UIOP_Connector::make_connection, "
                    "going to wait for connection completion on local"
                    "handle [%d]\n",
                    svc_handler->get_handle ()));

       // Wait for connection completion.  No need to specify timeout
       // to wait() since the correct timeout was passed to the
       // Connector. The Connector will close the handler in the case
       // of timeouts, so the event will complete (either success or
       // failure) within timeout.
      result =
        this->active_connect_strategy_->wait (svc_handler,
                                              0);

      if (TAO_debug_level > 2)
        {
          ACE_DEBUG ((LM_DEBUG,
                      "TAO (%P|%t) - UIOP_Connector::make_connection"
                      "wait done for handle[%d], result = %d\n",
                      svc_handler->get_handle (), result));
        }

       // There are three possibilities when wait() returns: (a)
       // connection succeeded; (b) connection failed; (c) wait()
       // failed because of some other error.  It is easy to deal with
       // (a) and (b).  (c) is tricky since the connection is still
       // pending and may get completed by some other thread.  The
       // following code deals with (c).

       // Check if the handler has been closed.
       int closed =
         svc_handler->is_closed ();

       // In case of failures and close() has not be called.
       if (result == -1 &&
           !closed)
         {
           // First, cancel from connector.
           this->base_connector_.cancel (svc_handler);

           // Double check to make sure the handler has not been
           // closed yet.  This double check is required to ensure
           // that the connection handler was not closed yet by some
           // other thread since it was still registered with the
           // connector.  Once connector.cancel() has been processed,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?