SHMIOP_Connector.cpp

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

Generated on Thu Nov 9 13:39:30 2006 for TAO_Strategies by doxygen 1.3.6