SHMIOP_Connector.cpp

Go to the documentation of this file.
00001 // $Id: SHMIOP_Connector.cpp 79169 2007-08-02 08:41:23Z johnnyw $
00002 
00003 
00004 #include "tao/Strategies/SHMIOP_Connector.h"
00005 
00006 #if defined (TAO_HAS_SHMIOP) && (TAO_HAS_SHMIOP != 0)
00007 
00008 #include "tao/Strategies/SHMIOP_Profile.h"
00009 #include "tao/Strategies/SHMIOP_Endpoint.h"
00010 #include "tao/debug.h"
00011 #include "tao/Base_Transport_Property.h"
00012 #include "tao/ORB_Core.h"
00013 #include "tao/Client_Strategy_Factory.h"
00014 #include "tao/SystemException.h"
00015 #include "tao/Transport_Cache_Manager.h"
00016 #include "tao/Thread_Lane_Resources.h"
00017 #include "tao/Blocked_Connect_Strategy.h"
00018 #include "ace/OS_NS_strings.h"
00019 
00020 ACE_RCSID (Strategies,
00021            SHMIOP_Connector,
00022            "$Id: SHMIOP_Connector.cpp 79169 2007-08-02 08:41:23Z johnnyw $")
00023 
00024 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00025 
00026 TAO_SHMIOP_Connector::TAO_SHMIOP_Connector (void)
00027   : TAO_Connector (TAO_TAG_SHMEM_PROFILE),
00028     connect_strategy_ (),
00029     base_connector_ ()
00030 {
00031 }
00032 
00033 TAO_SHMIOP_Connector::~TAO_SHMIOP_Connector (void)
00034 {
00035 }
00036 
00037 int
00038 TAO_SHMIOP_Connector::open (TAO_ORB_Core *orb_core)
00039 {
00040   this->orb_core (orb_core);
00041 
00042   // The SHMIOP always uses a blocked connect strategy
00043   // @todo: There are better ways of doing this. Let it be like this
00044   // for the  present.
00045   ACE_NEW_RETURN (this->active_connect_strategy_,
00046                   TAO_Blocked_Connect_Strategy (orb_core),
00047                   -1);
00048 
00049   // Our connect creation strategy
00050   TAO_SHMIOP_CONNECT_CREATION_STRATEGY *connect_creation_strategy = 0;
00051 
00052   ACE_NEW_RETURN (connect_creation_strategy,
00053                   TAO_SHMIOP_CONNECT_CREATION_STRATEGY
00054                       (orb_core->thr_mgr (),
00055                        orb_core),
00056                   -1);
00057 
00058   /// Our activation strategy
00059   TAO_SHMIOP_CONNECT_CONCURRENCY_STRATEGY *concurrency_strategy = 0;
00060 
00061   ACE_NEW_RETURN (concurrency_strategy,
00062                   TAO_SHMIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core),
00063                   -1);
00064 
00065   if (this->base_connector_.open (this->orb_core ()->reactor (),
00066                                   connect_creation_strategy,
00067                                   &this->connect_strategy_,
00068                                   concurrency_strategy) == -1)
00069     return -1;
00070   // We can take advantage of the multithreaded shared-memory transport
00071   // if the client will block on read (i.e., will not allow callback.)
00072   else if (orb_core->client_factory ()->allow_callback () == 0)
00073 
00074     {
00075       this->base_connector_.connector ().preferred_strategy (ACE_MEM_IO::MT);
00076       this->connect_strategy_.connector ().preferred_strategy (ACE_MEM_IO::MT);
00077     }
00078   return 0;
00079 }
00080 
00081 int
00082 TAO_SHMIOP_Connector::close (void)
00083 {
00084   delete this->base_connector_.concurrency_strategy ();
00085   delete this->base_connector_.creation_strategy ();
00086   return this->base_connector_.close ();
00087 }
00088 
00089 int
00090 TAO_SHMIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
00091 {
00092   if (endpoint->tag () != TAO_TAG_SHMEM_PROFILE)
00093     return -1;
00094 
00095   TAO_SHMIOP_Endpoint *shmiop_endpoint =
00096     dynamic_cast <TAO_SHMIOP_Endpoint *>(endpoint);
00097   if (shmiop_endpoint == 0)
00098     return -1;
00099 
00100    const ACE_INET_Addr &remote_address =
00101      shmiop_endpoint->object_addr ();
00102 
00103    // Verify that the remote ACE_INET_Addr was initialized properly.
00104    // Failure can occur if hostname lookup failed when initializing the
00105    // remote ACE_INET_Addr.
00106    if (remote_address.get_type () != AF_INET)
00107      {
00108        if (TAO_debug_level > 0)
00109          {
00110            ACE_ERROR ((LM_ERROR,
00111                        ACE_TEXT ("TAO (%P|%t) SHMIOP connection failed.\n")
00112                        ACE_TEXT ("TAO (%P|%t) This is most likely ")
00113                        ACE_TEXT ("due to a hostname lookup ")
00114                        ACE_TEXT ("failure.\n")));
00115          }
00116 
00117        return -1;
00118      }
00119 
00120    return 0;
00121 
00122 }
00123 
00124 TAO_Transport *
00125 TAO_SHMIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *,
00126                                        TAO_Transport_Descriptor_Interface &desc,
00127                                        ACE_Time_Value *timeout)
00128 {
00129   if (TAO_debug_level > 0)
00130       ACE_DEBUG ((LM_DEBUG,
00131                   ACE_TEXT ("TAO (%P|%t) - SHMIOP_Connector::make_connection, ")
00132                   ACE_TEXT ("looking for SHMIOP connection.\n")));
00133 
00134   TAO_SHMIOP_Endpoint *shmiop_endpoint =
00135     this->remote_endpoint (desc.endpoint ());
00136 
00137   if (shmiop_endpoint == 0)
00138     return 0;
00139 
00140   const ACE_INET_Addr &remote_address =
00141     shmiop_endpoint->object_addr ();
00142 
00143   if (TAO_debug_level > 2)
00144     ACE_DEBUG ((LM_DEBUG,
00145                 "TAO (%P|%t) - SHMIOP_Connector::make_connection, "
00146                 "making a new connection to <%s:%d>\n",
00147                 ACE_TEXT_CHAR_TO_TCHAR (shmiop_endpoint->host ()),
00148                 shmiop_endpoint->port ()));
00149 
00150   // Get the right synch options
00151   ACE_Synch_Options synch_options;
00152 
00153   this->active_connect_strategy_->synch_options (timeout,
00154                                                  synch_options);
00155 
00156   TAO_SHMIOP_Connection_Handler *svc_handler = 0;
00157 
00158   // Connect.
00159   int result = this->base_connector_.connect (svc_handler,
00160                                               remote_address,
00161                                               synch_options);
00162 
00163   // This call creates the service handler and bumps the #REFCOUNT# up
00164   // one extra.  There are two possibilities: (a) connection succeeds
00165   // immediately - in this case, the #REFCOUNT# on the handler is two;
00166   // (b) connection fails immediately - in this case, the #REFCOUNT#
00167   // on the handler is one since close() gets called on the handler.
00168   // We always use a blocking connection so the connection is never
00169   // pending.
00170 
00171   // Make sure that we always do a remove_reference
00172   ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler);
00173 
00174   // In case of errors.
00175   if (result == -1)
00176     {
00177       // Give users a clue to the problem.
00178       if (TAO_debug_level > 0)
00179         {
00180           ACE_ERROR ((LM_ERROR,
00181                       ACE_TEXT ("TAO (%P|%t) - SHMIOP_Connector::make_connection, ")
00182                       ACE_TEXT ("connection to <%s:%u> failed (%p)\n"),
00183                       ACE_TEXT_CHAR_TO_TCHAR (shmiop_endpoint->host ()),
00184                       shmiop_endpoint->port (),
00185                       ACE_TEXT ("errno")));
00186         }
00187 
00188       return 0;
00189     }
00190 
00191   if (svc_handler->keep_waiting ())
00192     {
00193       svc_handler->connection_pending ();
00194     }
00195 
00196   if (svc_handler->error_detected ())
00197     {
00198       svc_handler->cancel_pending_connection ();
00199     }
00200 
00201   TAO_Transport *transport =
00202     svc_handler->transport ();
00203 
00204   // At this point, the connection has be successfully connected.
00205   // #REFCOUNT# is one.
00206   if (TAO_debug_level > 2)
00207     ACE_DEBUG ((LM_DEBUG,
00208                 "TAO (%P|%t) - SHMIOP_Connector::make_connection, "
00209                 "new %s connection to <%s:%d> on Transport[%d]\n",
00210                 transport->is_connected() ? "connected" : "not connected",
00211                 ACE_TEXT_CHAR_TO_TCHAR (shmiop_endpoint->host ()),
00212                 shmiop_endpoint->port (),
00213                 svc_handler->peer ().get_handle ()));
00214 
00215   // Add the handler to Cache
00216   int retval =
00217     this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc,
00218                                                                              transport);
00219 
00220   // Failure in adding to cache.
00221   if (retval != 0)
00222     {
00223       // Close the handler.
00224       svc_handler->close ();
00225 
00226       if (TAO_debug_level > 0)
00227         {
00228           ACE_ERROR ((LM_ERROR,
00229                       ACE_TEXT("TAO (%P|%t) - SHMIOP_Connector::make_connection, ")
00230                       ACE_TEXT("could not add the new connection to cache\n")));
00231         }
00232 
00233       return 0;
00234     }
00235 
00236   if (svc_handler->error_detected ())
00237     {
00238       svc_handler->cancel_pending_connection ();
00239       transport->purge_entry();
00240       return 0;
00241     }
00242 
00243   if (transport->is_connected () &&
00244       transport->wait_strategy ()->register_handler () != 0)
00245     {
00246       // Registration failures.
00247 
00248       // Purge from the connection cache, if we are not in the cache, this
00249       // just does nothing.
00250       (void) transport->purge_entry ();
00251 
00252       // Close the handler.
00253       (void) transport->close_connection ();
00254 
00255       if (TAO_debug_level > 0)
00256         ACE_ERROR ((LM_ERROR,
00257                     "TAO (%P|%t) - SHMIOP_Connector [%d]::make_connection, "
00258                     "could not register the transport in the reactor.\n",
00259                     transport->id ()));
00260 
00261       return 0;
00262     }
00263 
00264   return transport;
00265 }
00266 
00267 TAO_Profile *
00268 TAO_SHMIOP_Connector::create_profile (TAO_InputCDR& cdr)
00269 {
00270   TAO_Profile *pfile = 0;
00271   ACE_NEW_RETURN (pfile,
00272                   TAO_SHMIOP_Profile (this->orb_core ()),
00273                   0);
00274 
00275   int r = pfile->decode (cdr);
00276   if (r == -1)
00277     {
00278       pfile->_decr_refcnt ();
00279       pfile = 0;
00280     }
00281 
00282   return pfile;
00283 }
00284 
00285 TAO_Profile *
00286 TAO_SHMIOP_Connector::make_profile (void)
00287 {
00288   // The endpoint should be of the form:
00289   //    N.n@port/object_key
00290   // or:
00291   //    port/object_key
00292 
00293   TAO_Profile *profile = 0;
00294   ACE_NEW_THROW_EX (profile,
00295                     TAO_SHMIOP_Profile (this->orb_core ()),
00296                     CORBA::NO_MEMORY (
00297                       CORBA::SystemException::_tao_minor_code (
00298                         TAO::VMCID,
00299                         ENOMEM),
00300                       CORBA::COMPLETED_NO));
00301 
00302   return profile;
00303 }
00304 
00305 int
00306 TAO_SHMIOP_Connector::check_prefix (const char *endpoint)
00307 {
00308   // Check for a valid string
00309   if (!endpoint || !*endpoint)
00310     return -1;  // Failure
00311 
00312   const char *protocol[] = { "shmiop", "shmioploc" };
00313 
00314   size_t slot = ACE_OS::strchr (endpoint, ':') - endpoint;
00315 
00316   size_t len0 = ACE_OS::strlen (protocol[0]);
00317   size_t len1 = ACE_OS::strlen (protocol[1]);
00318 
00319   // Check for the proper prefix in the IOR.  If the proper prefix
00320   // isn't in the IOR then it is not an IOR we can use.
00321   if (slot == len0
00322       && ACE_OS::strncasecmp (endpoint, protocol[0], len0) == 0)
00323     return 0;
00324   else if (slot == len1
00325            && ACE_OS::strncasecmp (endpoint, protocol[1], len1) == 0)
00326     return 0;
00327 
00328   return -1;
00329   // Failure: not an SHMIOP IOR
00330   // DO NOT throw an exception here.
00331 }
00332 
00333 char
00334 TAO_SHMIOP_Connector::object_key_delimiter (void) const
00335 {
00336   return TAO_SHMIOP_Profile::object_key_delimiter_;
00337 }
00338 
00339 TAO_SHMIOP_Endpoint *
00340 TAO_SHMIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint)
00341 {
00342   if (endpoint->tag () != TAO_TAG_SHMEM_PROFILE)
00343     return 0;
00344 
00345   TAO_SHMIOP_Endpoint *shmiop_endpoint =
00346     dynamic_cast <TAO_SHMIOP_Endpoint *>(endpoint);
00347   if (shmiop_endpoint == 0)
00348     return 0;
00349 
00350   return shmiop_endpoint;
00351 }
00352 
00353 int
00354 TAO_SHMIOP_Connector::cancel_svc_handler (
00355   TAO_Connection_Handler * svc_handler)
00356 {
00357   TAO_SHMIOP_Connection_Handler* handler=
00358     dynamic_cast<TAO_SHMIOP_Connection_Handler*>(svc_handler);
00359 
00360   if (handler)
00361     // Cancel from the connector
00362     return this->base_connector_.cancel (handler);
00363 
00364   return -1;
00365 }
00366 
00367 TAO_END_VERSIONED_NAMESPACE_DECL
00368 
00369 #endif /* TAO_HAS_SHMIOP && TAO_HAS_SHMIOP != 0 */

Generated on Tue Feb 2 17:47:18 2010 for TAO_Strategies by  doxygen 1.4.7