IIOP_Connector.cpp

Go to the documentation of this file.
00001 #include "tao/IIOP_Connector.h"
00002 
00003 #if defined (TAO_HAS_IIOP) && (TAO_HAS_IIOP != 0)
00004 
00005 #include "tao/IIOP_Profile.h"
00006 #include "tao/debug.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/Protocols_Hooks.h"
00009 #include "tao/Connect_Strategy.h"
00010 #include "tao/Thread_Lane_Resources.h"
00011 #include "tao/Profile_Transport_Resolver.h"
00012 #include "tao/Base_Transport_Property.h"
00013 #include "tao/Transport.h"
00014 #include "tao/Wait_Strategy.h"
00015 #include "tao/SystemException.h"
00016 #include "tao/LF_Multi_Event.h"
00017 #include "ace/OS_NS_strings.h"
00018 #include "ace/OS_NS_string.h"
00019 #include "ace/OS_NS_time.h"
00020 #include "ace/CORBA_macros.h"
00021 
00022 ACE_RCSID (tao,
00023            IIOP_Connector,
00024            "$Id: IIOP_Connector.cpp 80199 2007-12-05 14:49:58Z johnnyw $")
00025 
00026 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00027 
00028 // Uncomment *one* of the the following defines if you want to explicitly induce
00029 // the race condition defined in Bug 2654. These enable the introduction of a
00030 // slight delay during connection completion processing.
00031 // A - before checking the connection_pending status
00032 // B - after A but before checking the connection error result
00033 // C - acter B but before caching
00034 // D - after caching
00035 //#define INDUCE_BUG_2654_A
00036 //#define INDUCE_BUG_2654_B
00037 //#define INDUCE_BUG_2654_C
00038 //#define INDUCE_BUG_2654_D
00039 
00040 //-----------------------------------------------------------------------------
00041 
00042 /**
00043  * @class TAO_Event_Handler_Array_var
00044  *
00045  * @brief Auto pointer like class for an array of Event Handlers.
00046  *
00047  * Used to manage lifecycle of handlers. This class calls
00048  * ACE_Event_Handler::remove_reference() on each handler in its destructor
00049  * This class started out life as a replacement for the ACE_Event_Handle_var
00050  * but is now pared down to be very specific in its role..
00051  */
00052 class TAO_IIOP_Connection_Handler_Array_Guard
00053 {
00054 public:
00055   TAO_IIOP_Connection_Handler_Array_Guard (TAO_IIOP_Connection_Handler **p, unsigned count);
00056   ~TAO_IIOP_Connection_Handler_Array_Guard (void);
00057 
00058 private:
00059   /// Handler.
00060   TAO_IIOP_Connection_Handler **ptr_;
00061   unsigned count_;
00062 };
00063 
00064 TAO_IIOP_Connection_Handler_Array_Guard::TAO_IIOP_Connection_Handler_Array_Guard (TAO_IIOP_Connection_Handler **p,
00065                                                           unsigned count)
00066   : ptr_ (p),
00067     count_ (count)
00068 {
00069 }
00070 
00071 TAO_IIOP_Connection_Handler_Array_Guard::~TAO_IIOP_Connection_Handler_Array_Guard (void)
00072 {
00073   ACE_Errno_Guard eguard (errno);
00074   if (this->ptr_ != 0)
00075     {
00076       for (unsigned i = 0; i < this->count_; i++)
00077         this->ptr_[i]->remove_reference ();
00078     }
00079 }
00080 
00081 //---------------------------------------------------------------------------
00082 
00083 
00084 TAO_IIOP_Connector::~TAO_IIOP_Connector (void)
00085 {
00086 }
00087 
00088 //@@ TAO_CONNECTOR_SPL_COPY_HOOK_START
00089 TAO_IIOP_Connector::TAO_IIOP_Connector (void)
00090   : TAO_Connector (IOP::TAG_INTERNET_IOP)
00091   , connect_strategy_ ()
00092   , base_connector_ ()
00093 {
00094 }
00095 
00096 int
00097 TAO_IIOP_Connector::open (TAO_ORB_Core *orb_core)
00098 {
00099   // @todo: The functionality of the following two statements could
00100   // be done in the constructor, but that involves changing the
00101   // interface of the pluggable transport factory.
00102 
00103   // Set the ORB Core
00104   this->orb_core (orb_core);
00105 
00106   // Create our connect strategy
00107   if (this->create_connect_strategy () == -1)
00108     return -1;
00109 
00110   /// Our connect creation strategy
00111   TAO_IIOP_CONNECT_CREATION_STRATEGY *connect_creation_strategy = 0;
00112 
00113   ACE_NEW_RETURN (connect_creation_strategy,
00114                   TAO_IIOP_CONNECT_CREATION_STRATEGY
00115                       (orb_core->thr_mgr (),
00116                        orb_core),
00117                   -1);
00118 
00119   /// Our activation strategy
00120   TAO_IIOP_CONNECT_CONCURRENCY_STRATEGY *concurrency_strategy = 0;
00121 
00122   ACE_NEW_RETURN (concurrency_strategy,
00123                   TAO_IIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core),
00124                   -1);
00125 
00126   return this->base_connector_.open (this->orb_core ()->reactor (),
00127                                      connect_creation_strategy,
00128                                      &this->connect_strategy_,
00129                                      concurrency_strategy);
00130 }
00131 
00132 int
00133 TAO_IIOP_Connector::close (void)
00134 {
00135   delete this->base_connector_.concurrency_strategy ();
00136   delete this->base_connector_.creation_strategy ();
00137   return this->base_connector_.close ();
00138 }
00139 
00140 int
00141 TAO_IIOP_Connector::supports_parallel_connects(void) const
00142 {
00143   return 1;
00144 }
00145 
00146 int
00147 TAO_IIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
00148 {
00149   TAO_IIOP_Endpoint *iiop_endpoint =
00150     this->remote_endpoint (endpoint);
00151 
00152   if (iiop_endpoint == 0)
00153     return -1;
00154 
00155    const ACE_INET_Addr &remote_address =
00156      iiop_endpoint->object_addr ();
00157 
00158    // Verify that the remote ACE_INET_Addr was initialized properly.
00159    // Failure can occur if hostname lookup failed when initializing the
00160    // remote ACE_INET_Addr.
00161 #if defined (ACE_HAS_IPV6)
00162    if (remote_address.get_type () != AF_INET &&
00163        remote_address.get_type () != AF_INET6)
00164 #else /* ACE_HAS_IPV6 */
00165    if (remote_address.get_type () != AF_INET)
00166 #endif /* !ACE_HAS_IPV6 */
00167      {
00168        if (TAO_debug_level > 0)
00169          {
00170            ACE_DEBUG ((LM_DEBUG,
00171                        ACE_TEXT ("TAO (%P|%t) - IIOP connection failed.\n")
00172                        ACE_TEXT ("     This is most likely ")
00173                        ACE_TEXT ("due to a hostname lookup ")
00174                        ACE_TEXT ("failure.\n")));
00175          }
00176 
00177        return -1;
00178      }
00179 
00180    return 0;
00181 }
00182 
00183 TAO_Transport *
00184 TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r,
00185                                      TAO_Transport_Descriptor_Interface &desc,
00186                                      ACE_Time_Value *timeout)
00187 {
00188   TAO_IIOP_Connection_Handler *svc_handler = 0;
00189   TAO_IIOP_Endpoint *iiop_endpoint =
00190     this->remote_endpoint (desc.endpoint());
00191   int result = -1;
00192   if (iiop_endpoint == 0)
00193     return 0;
00194 
00195   result = this->begin_connection (svc_handler, r, iiop_endpoint, timeout);
00196 
00197   if (result == -1 && errno != EWOULDBLOCK)
00198     {
00199       // connect completed unsuccessfully
00200       svc_handler->remove_reference();
00201        // Give users a clue to the problem.
00202       if (TAO_debug_level > 1)
00203         {
00204           ACE_ERROR ((LM_ERROR,
00205                       ACE_TEXT ("TAO (%P|%t) IIOP_Connector::make_connection, ")
00206                       ACE_TEXT("connection to <%s:%d> failed (%p)\n"),
00207                       ACE_TEXT_CHAR_TO_TCHAR (iiop_endpoint->host ()),
00208                       iiop_endpoint->port (),
00209                       ACE_TEXT("errno")));
00210         }
00211     return 0;
00212     }
00213   TAO_IIOP_Connection_Handler **sh_ptr = &svc_handler;
00214   TAO_IIOP_Endpoint **ep_ptr = &iiop_endpoint;
00215   TAO_LF_Multi_Event mev;
00216   mev.add_event (svc_handler);
00217 
00218   return this->complete_connection (result,
00219                                     desc,
00220                                     sh_ptr,
00221                                     ep_ptr,
00222                                     1U,
00223                                     r,
00224                                     &mev,
00225                                     timeout);
00226 }
00227 
00228 TAO_Transport *
00229 TAO_IIOP_Connector::make_parallel_connection (
00230   TAO::Profile_Transport_Resolver * r,
00231   TAO_Transport_Descriptor_Interface & desc,
00232   ACE_Time_Value * timeout)
00233 {
00234   TAO_Endpoint *root_ep = desc.endpoint();
00235   unsigned max_count = 1;
00236   unsigned long ns_stagger =
00237     this->orb_core ()->orb_params ()->parallel_connect_delay ();
00238   unsigned long sec_stagger = ns_stagger/1000;
00239   ns_stagger = (ns_stagger % 1000) * 1000000;
00240   for (TAO_Endpoint *ep = root_ep->next_filtered (this->orb_core(), 0);
00241        ep != 0;
00242        ep = ep->next_filtered (this->orb_core(), root_ep))
00243     ++max_count;
00244 
00245   if (TAO_debug_level > 2)
00246     ACE_DEBUG ((LM_DEBUG,
00247                 ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::")
00248                 ACE_TEXT ("make_parallel_connection, ")
00249                 ACE_TEXT ("to %d endpoints\n"), max_count));
00250   TAO_IIOP_Endpoint **eplist = 0;
00251   TAO_IIOP_Connection_Handler **shlist = 0;
00252   ACE_NEW_RETURN (shlist, TAO_IIOP_Connection_Handler *[max_count], 0);
00253   ACE_NEW_RETURN (eplist, TAO_IIOP_Endpoint *[max_count], 0);
00254 
00255   TAO_LF_Multi_Event mev;
00256   int result = 0;
00257   unsigned count = 0;
00258   for (TAO_Endpoint *ep = root_ep->next_filtered (this->orb_core(),0);
00259        ep != 0;
00260        ep = ep->next_filtered(this->orb_core(),root_ep))
00261     {
00262       eplist[count] = this->remote_endpoint (ep);
00263       shlist[count] = 0;
00264       result = this->begin_connection (shlist[count],
00265                                        r,
00266                                        eplist[count],
00267                                        timeout);
00268 
00269       // The connection may fail because it is slow, or for other reasons.
00270       // If it was an incomplete non-blocking connection, add it to the list
00271       // to be waited on, otherwise remove the reference to the handler and
00272       // move on to the next endpoint.
00273       if (result == -1)
00274         {
00275           if (errno == EWOULDBLOCK)
00276             {
00277               mev.add_event(shlist[count++]);
00278               if (ep->next() != 0)
00279                 {
00280                   struct timespec nsleep = {sec_stagger, ns_stagger};
00281                   ACE_OS::nanosleep (&nsleep);
00282                   result = this->active_connect_strategy_->poll (&mev);
00283                   if (result != -1)
00284                     break;
00285                 }
00286             }
00287           else
00288             {
00289               shlist[count]->remove_reference(); // done bump the list count
00290             }
00291           continue;
00292         }
00293 
00294       if (result != -1) // we have a winner!
00295         {
00296           count++;
00297           break; // no waiting involved since a connection is completed
00298         }
00299     }
00300 
00301   TAO_Transport *winner = 0;
00302   if (count > 0) // only complete if at least one pending or success
00303     winner = this->complete_connection (result,
00304                                         desc,
00305                                         shlist,
00306                                         eplist,
00307                                         count,r,
00308                                         &mev,
00309                                         timeout);
00310 
00311   delete [] shlist; // reference reductions should have been done already
00312   delete [] eplist;
00313   return winner;
00314 }
00315 
00316 int
00317 TAO_IIOP_Connector::begin_connection (TAO_IIOP_Connection_Handler *&svc_handler,
00318                                       TAO::Profile_Transport_Resolver *r,
00319                                       TAO_IIOP_Endpoint *iiop_endpoint,
00320                                       ACE_Time_Value *timeout)
00321 {
00322   const ACE_INET_Addr &remote_address =
00323     iiop_endpoint->object_addr ();
00324 
00325   u_short port = 0;
00326   const ACE_UINT32 ia_any = INADDR_ANY;
00327   ACE_INET_Addr local_addr(port, ia_any);
00328 
00329   if (iiop_endpoint->is_preferred_network ())
00330     local_addr.set (port,
00331                     iiop_endpoint->preferred_network ());
00332 #if defined (ACE_HAS_IPV6)
00333   else if (remote_address.get_type () == AF_INET6)
00334     local_addr.set (port,
00335                     ACE_IPV6_ANY);
00336 #endif /* ACE_HAS_IPV6 */
00337 
00338   if (TAO_debug_level > 2)
00339     ACE_DEBUG ((LM_DEBUG,
00340                 ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::begin_connection, ")
00341                 ACE_TEXT ("to <%s:%d> which should %s\n"),
00342                 ACE_TEXT_CHAR_TO_TCHAR(iiop_endpoint->host()),
00343                 iiop_endpoint->port(),
00344                 r->blocked_connect () ? ACE_TEXT("block") : ACE_TEXT("nonblock")));
00345 
00346   // Get the right synch options
00347   ACE_Synch_Options synch_options;
00348 
00349   this->active_connect_strategy_->synch_options (timeout,
00350                                                  synch_options);
00351 
00352   // The code used to set the timeout to zero, with the intent of
00353   // polling the reactor for connection completion. However, the side-effect
00354   // was to cause the connection to timeout immediately.
00355 
00356   svc_handler = 0;
00357 
00358   int result =
00359     this->base_connector_.connect (svc_handler,
00360                                    remote_address,
00361                                    synch_options,
00362                                    local_addr);
00363 
00364   // The connect() method creates the service handler and bumps the
00365   // #REFCOUNT# up one extra.  There are four possibilities from
00366   // calling connect(): (a) connection succeeds immediately - in this
00367   // case, the #REFCOUNT# on the handler is two; (b) connection
00368   // completion is pending - in this case, the #REFCOUNT# on the
00369   // handler is also two; (c) connection fails immediately - in this
00370   // case, the #REFCOUNT# on the handler is one since close() gets
00371   // called on the handler; (d) the connect immediately returns when we
00372   // have specified that it shouldn't block.
00373   //
00374   // The extra reference count in
00375   // TAO_Connect_Creation_Strategy::make_svc_handler() is needed in
00376   // the case when connection completion is pending and we are going
00377   // to wait on a variable in the handler to changes, signifying
00378   // success or failure.  Note, that this increment cannot be done
00379   // once the connect() returns since this might be too late if
00380   // another thread pick up the completion and potentially deletes the
00381   // handler before we get a chance to increment the reference count.
00382   return result;
00383 }
00384 
00385 TAO_Transport *
00386 TAO_IIOP_Connector::complete_connection (int result,
00387                                          TAO_Transport_Descriptor_Interface &desc,
00388                                          TAO_IIOP_Connection_Handler **&sh_list,
00389                                          TAO_IIOP_Endpoint **ep_list,
00390                                          unsigned count,
00391                                          TAO::Profile_Transport_Resolver *r,
00392                                          TAO_LF_Multi_Event *mev,
00393                                          ACE_Time_Value *timeout)
00394 {
00395   // Make sure that we always do a remove_reference for every member
00396   // of the list
00397   TAO_IIOP_Connection_Handler_Array_Guard svc_handler_auto_ptr (sh_list,count);
00398   TAO_Transport *transport  = 0;
00399   TAO_Transport **tlist = 0;
00400   ACE_NEW_RETURN (tlist,TAO_Transport*[count],0);
00401 
00402   //  populate the transport list
00403   for (unsigned i = 0; i < count; i++)
00404     tlist[i] = sh_list[i]->transport();
00405 
00406   if (result != -1)
00407     {
00408       // We received a compeleted connection and 0 or more pending.
00409       // the winner is the last member of the list, because the
00410       // iterator stopped on a successful connect.
00411       transport = tlist[count-1];
00412     }
00413   else
00414     {
00415       if (count == 1)
00416         {
00417           transport = tlist[0];
00418           if (!this->wait_for_connection_completion (r,
00419                                                      transport,
00420                                                      timeout))
00421             {
00422               if (TAO_debug_level > 2)
00423                 ACE_ERROR ((LM_ERROR,
00424                             ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::")
00425                             ACE_TEXT ("complete_connection, wait for completion ")
00426                             ACE_TEXT ("failed for 1 pending connect\n")));
00427             }
00428         }
00429       else
00430         {
00431           if (!this->wait_for_connection_completion (r,
00432                                                      transport,
00433                                                      tlist,
00434                                                      count,
00435                                                      mev,
00436                                                      timeout))
00437             {
00438               if (TAO_debug_level > 2)
00439                 ACE_ERROR ((LM_ERROR,
00440                             ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::")
00441                             ACE_TEXT ("complete_connection, wait for completion ")
00442                             ACE_TEXT ("failed for %d pending connects\n"),
00443                             count));
00444             }
00445         }
00446     }
00447 
00448 #if defined (INDUCE_BUG_2654_A)
00449   // This is where the fatal error would occur. A pending asynch
00450   // connection would fail, the failure handled by another thread,
00451   // closing the connection.  However the remainder of this method
00452   // only checked to see if the keep_waiting status was true, and bump
00453   // the refcount then. However if the status was really
00454   // error_detected, then no bump in refcount occured allowing the
00455   // connection_handler's close_handler method to effectively steal
00456   // the reference to be handed back to the caller. That would then
00457   // trigger an abort as the profile_transport_resolver (our caller)
00458   // to delete the transport while it is still cached.
00459   ACE_Time_Value udelay(0,600);
00460   struct timespec ts = udelay;
00461   ACE_OS::nanosleep (&ts);
00462 #endif // INDUCE_BUG_2654_A
00463 
00464   int retval = -1;
00465 
00466   // At this point, the connection has been successfully created
00467   // connected or not connected, but we have a connection.
00468   TAO_IIOP_Connection_Handler *svc_handler = 0;
00469   TAO_IIOP_Endpoint *iiop_endpoint = 0;
00470 
00471   if (transport != 0)
00472     {
00473       if (count == 1)
00474         {
00475           svc_handler = sh_list[0];
00476           iiop_endpoint = ep_list[0];
00477         }
00478       else
00479         {
00480           for (unsigned i = 0; i < count; i++)
00481             {
00482               if (transport == tlist[i])
00483                 {
00484                   svc_handler = sh_list[i];
00485                   iiop_endpoint = ep_list[i];
00486                   break;
00487                 }
00488             }
00489         }
00490     }
00491 
00492 
00493   // Done with the transport list. It was a temporary that did not
00494   // affect the reference count.
00495   delete [] tlist;
00496 
00497   // In case of errors transport is zero
00498   if (transport == 0)
00499     {
00500       // Give users a clue to the problem.
00501       if (TAO_debug_level > 3)
00502         {
00503           for (unsigned i = 0; i < count; i++)
00504             {
00505               ACE_ERROR ((LM_ERROR,
00506                           ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::complete_connection,")
00507                           ACE_TEXT (" connection to <%s:%d> failed (%p)\n"),
00508                           ACE_TEXT_CHAR_TO_TCHAR (ep_list[i]->host ()),
00509                           ep_list[i]->port (),
00510                           ACE_TEXT("errno")));
00511             }
00512         }
00513       return 0;
00514     }
00515 
00516   if (svc_handler->keep_waiting())
00517     {
00518       svc_handler->connection_pending();
00519     }
00520 
00521 #if defined (INDUCE_BUG_2654_B)
00522   // It is possible for the connection failure to be processed after bumping
00523   // the reference count and before we plan to cache the connection. Prior to
00524   // fixing bug 2654, this would lead to a failed connection in the cache.
00525   // Though not a fatal condition, it was certainly wasteful of resources.
00526   ACE_Time_Value udelay(0,600);
00527   struct timespec ts = udelay;
00528   ACE_OS::nanosleep (&ts);
00529 #endif // INDUCE_BUG_2654_B
00530 
00531   // Fix for bug 2654.
00532   if (transport->connection_handler()->error_detected())
00533     {
00534       if (TAO_debug_level > 0)
00535         ACE_DEBUG((LM_DEBUG,
00536                    ACE_TEXT("TAO (%P|%t) - IIOP_Connector::make_connection, ")
00537                    ACE_TEXT("transport in error before cache! \n")));
00538       transport->connection_handler()->cancel_pending_connection();
00539       return 0;
00540     }
00541 
00542   if (TAO_debug_level > 2)
00543     {
00544     ACE_DEBUG ((LM_DEBUG,
00545                   ACE_TEXT ("TAO (%P|%t) - IIOP_Connector::make_connection, ")
00546                   ACE_TEXT ("new %s connection to <%s:%d> on Transport[%d]\n"),
00547                   transport->is_connected() ?
00548                   ACE_TEXT("connected") : ACE_TEXT("not connected"),
00549                   ACE_TEXT_CHAR_TO_TCHAR (iiop_endpoint->host ()),
00550                 iiop_endpoint->port (),
00551                 svc_handler->peer ().get_handle ()));
00552     }
00553 
00554 #if defined (INDUCE_BUG_2654_C)
00555   // This sets up the possibility that a failed connection is detected after we
00556   // checked the connection status but before we cached the connection. This
00557   // will allow a failed connection to be cached
00558   ACE_Time_Value udelay(0,600);
00559   struct timespec ts = udelay;
00560   ACE_OS::nanosleep (&ts);
00561 #endif // INDUCE_BUG_2654_C
00562 
00563 
00564   // Add the handler to Cache
00565   if (count == 1 || desc.reset_endpoint(iiop_endpoint))
00566     {
00567       retval = this->orb_core ()->
00568         lane_resources ().transport_cache ().cache_transport (&desc,
00569                                                               transport);
00570     }
00571 
00572   // Failure in adding to cache
00573   if (retval != 0)
00574     {
00575       // Close the handler.
00576       svc_handler->close ();
00577 
00578       if (TAO_debug_level > 0)
00579         {
00580           ACE_ERROR ((LM_ERROR,
00581                       ACE_TEXT ("TAO (%P|%t) IIOP_Connector::make_connection, ")
00582                       ACE_TEXT ("could not add new connection to cache\n")));
00583         }
00584 
00585       return 0;
00586     }
00587 
00588   // Other part of fix for bug 2654.
00589   // It is possible that after checking for a connection failure but
00590   // before caching, the connection really failed, thus an invalid
00591   // connection is put into the cache. Thus we do one last status
00592   // check before handing the connection back to the caller.
00593   if (svc_handler->error_detected())
00594     {
00595       if (TAO_debug_level > 0)
00596         ACE_DEBUG((LM_DEBUG,
00597                    ACE_TEXT("TAO (%P|%t) - IIOP_Connector::make_connection, ")
00598                    ACE_TEXT("transport in error after cache! \n")));
00599       svc_handler->cancel_pending_connection();
00600       transport->purge_entry();
00601       return 0;
00602     }
00603 
00604 
00605 #if defined (INDUCE_BUG_2654_D)
00606   // at this point the connection handler's close connection will manage
00607   // purging the entry from the cache so we are fine there.
00608   ACE_Time_Value udelay(0,600);
00609   struct timespec ts = udelay;
00610   ACE_OS::nanosleep (&ts);
00611 #endif // INDUCE_BUG_2654_D
00612 
00613   if (transport->is_connected () &&
00614       transport->wait_strategy ()->register_handler () != 0)
00615     {
00616       // Registration failures.
00617 
00618       // Purge from the connection cache, if we are not in the cache, this
00619       // just does nothing.
00620       (void) transport->purge_entry ();
00621 
00622       // Close the handler.
00623       (void) transport->close_connection ();
00624 
00625       if (TAO_debug_level > 0)
00626         ACE_ERROR ((LM_ERROR,
00627                     ACE_TEXT ("TAO (%P|%t) IIOP_Connector [%d]::make_connection, ")
00628                     ACE_TEXT ("could not register the transport ")
00629                     ACE_TEXT ("in the reactor.\n"),
00630                     transport->id ()));
00631 
00632       return 0;
00633     }
00634 
00635   return transport;
00636 }
00637 
00638 TAO_Profile *
00639 TAO_IIOP_Connector::create_profile (TAO_InputCDR& cdr)
00640 {
00641   TAO_Profile *pfile = 0;
00642   ACE_NEW_RETURN (pfile,
00643                   TAO_IIOP_Profile (this->orb_core ()),
00644                   0);
00645 
00646   const int r = pfile->decode (cdr);
00647   if (r == -1)
00648     {
00649       pfile->_decr_refcnt ();
00650       pfile = 0;
00651     }
00652 
00653   return pfile;
00654 }
00655 
00656 TAO_Profile *
00657 TAO_IIOP_Connector::make_profile (void)
00658 {
00659   // The endpoint should be of the form:
00660   //    N.n@host:port/object_key
00661   // or:
00662   //    host:port/object_key
00663 
00664   TAO_Profile *profile = 0;
00665   ACE_NEW_THROW_EX (profile,
00666                     TAO_IIOP_Profile (this->orb_core ()),
00667                     CORBA::NO_MEMORY (
00668                       CORBA::SystemException::_tao_minor_code (
00669                         0,
00670                         ENOMEM),
00671                       CORBA::COMPLETED_NO));
00672 
00673   return profile;
00674 }
00675 
00676 int
00677 TAO_IIOP_Connector::check_prefix (const char *endpoint)
00678 {
00679   // Check for a valid string
00680   if (!endpoint || !*endpoint)
00681     return -1;  // Failure
00682 
00683   static const char *protocol[] = { "iiop", "iioploc" };
00684 
00685   size_t const slot = ACE_OS::strchr (endpoint, ':') - endpoint;
00686   if (slot == 0) // an empty string is valid for corbaloc.
00687     return 0;
00688 
00689   size_t const len0 = ACE_OS::strlen (protocol[0]);
00690   size_t const len1 = ACE_OS::strlen (protocol[1]);
00691 
00692   // Check for the proper prefix in the IOR.  If the proper prefix
00693   // isn't in the IOR then it is not an IOR we can use.
00694   if (slot == len0 && ACE_OS::strncasecmp (endpoint, protocol[0], len0) == 0)
00695     return 0;
00696   else if (slot == len1 && ACE_OS::strncasecmp (endpoint, protocol[1], len1) == 0)
00697     return 0;
00698 
00699   return -1;
00700   // Failure: not an IIOP IOR
00701   // DO NOT throw an exception here.
00702 }
00703 
00704 char
00705 TAO_IIOP_Connector::object_key_delimiter (void) const
00706 {
00707   return TAO_IIOP_Profile::object_key_delimiter_;
00708 }
00709 
00710 TAO_IIOP_Endpoint *
00711 TAO_IIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint)
00712 {
00713   if (endpoint->tag () != IOP::TAG_INTERNET_IOP)
00714     return 0;
00715 
00716   TAO_IIOP_Endpoint *iiop_endpoint =
00717     dynamic_cast<TAO_IIOP_Endpoint *> (endpoint );
00718 
00719   if (iiop_endpoint == 0)
00720     return 0;
00721 
00722   return iiop_endpoint;
00723 }
00724 
00725 int
00726 TAO_IIOP_Connector::cancel_svc_handler (
00727   TAO_Connection_Handler * svc_handler)
00728 {
00729   TAO_IIOP_Connection_Handler* handler=
00730     dynamic_cast<TAO_IIOP_Connection_Handler*>(svc_handler);
00731 
00732   // Cancel from the connector
00733   if (handler)
00734     {
00735       handler->abort();
00736       return this->base_connector_.cancel (handler);
00737     }
00738 
00739   return -1;
00740 }
00741 
00742 
00743 //@@ TAO_CONNECTOR_SPL_COPY_HOOK_END
00744 
00745 TAO_END_VERSIONED_NAMESPACE_DECL
00746 
00747 #endif /* TAO_HAS_IIOP && TAO_HAS_IIOP != 0 */

Generated on Tue Feb 2 17:37:52 2010 for TAO by  doxygen 1.4.7