summaryrefslogtreecommitdiff
path: root/ACE/TAO/tao/Strategies/SHMIOP_Connector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/TAO/tao/Strategies/SHMIOP_Connector.cpp')
-rw-r--r--ACE/TAO/tao/Strategies/SHMIOP_Connector.cpp362
1 files changed, 362 insertions, 0 deletions
diff --git a/ACE/TAO/tao/Strategies/SHMIOP_Connector.cpp b/ACE/TAO/tao/Strategies/SHMIOP_Connector.cpp
new file mode 100644
index 00000000000..aa4a0e7acd8
--- /dev/null
+++ b/ACE/TAO/tao/Strategies/SHMIOP_Connector.cpp
@@ -0,0 +1,362 @@
+// $Id$
+
+
+#include "tao/Strategies/SHMIOP_Connector.h"
+
+#if defined (TAO_HAS_SHMIOP) && (TAO_HAS_SHMIOP != 0)
+
+#include "tao/Strategies/SHMIOP_Profile.h"
+#include "tao/Strategies/SHMIOP_Endpoint.h"
+#include "tao/debug.h"
+#include "tao/Base_Transport_Property.h"
+#include "tao/ORB_Core.h"
+#include "tao/Client_Strategy_Factory.h"
+#include "tao/SystemException.h"
+#include "tao/Transport_Cache_Manager.h"
+#include "tao/Thread_Lane_Resources.h"
+#include "tao/Blocked_Connect_Strategy.h"
+#include "ace/OS_NS_strings.h"
+
+ACE_RCSID (Strategies,
+ SHMIOP_Connector,
+ "$Id$")
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_SHMIOP_Connector::TAO_SHMIOP_Connector (void)
+ : TAO_Connector (TAO_TAG_SHMEM_PROFILE),
+ connect_strategy_ (),
+ base_connector_ ()
+{
+}
+
+TAO_SHMIOP_Connector::~TAO_SHMIOP_Connector (void)
+{
+}
+
+int
+TAO_SHMIOP_Connector::open (TAO_ORB_Core *orb_core)
+{
+ this->orb_core (orb_core);
+
+ // The SHMIOP always uses a blocked connect strategy
+ // @todo: There are better ways of doing this. Let it be like this
+ // for the present.
+ ACE_NEW_RETURN (this->active_connect_strategy_,
+ TAO_Blocked_Connect_Strategy (orb_core),
+ -1);
+
+ // Our connect creation strategy
+ TAO_SHMIOP_CONNECT_CREATION_STRATEGY *connect_creation_strategy = 0;
+
+ ACE_NEW_RETURN (connect_creation_strategy,
+ TAO_SHMIOP_CONNECT_CREATION_STRATEGY
+ (orb_core->thr_mgr (),
+ orb_core),
+ -1);
+
+ /// Our activation strategy
+ TAO_SHMIOP_CONNECT_CONCURRENCY_STRATEGY *concurrency_strategy = 0;
+
+ ACE_NEW_RETURN (concurrency_strategy,
+ TAO_SHMIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core),
+ -1);
+
+ if (this->base_connector_.open (this->orb_core ()->reactor (),
+ connect_creation_strategy,
+ &this->connect_strategy_,
+ concurrency_strategy) == -1)
+ return -1;
+ // We can take advantage of the multithreaded shared-memory transport
+ // if the client will block on read (i.e., will not allow callback.)
+ else if (orb_core->client_factory ()->allow_callback () == 0)
+
+ {
+ this->base_connector_.connector ().preferred_strategy (ACE_MEM_IO::MT);
+ this->connect_strategy_.connector ().preferred_strategy (ACE_MEM_IO::MT);
+ }
+ return 0;
+}
+
+int
+TAO_SHMIOP_Connector::close (void)
+{
+ delete this->base_connector_.concurrency_strategy ();
+ delete this->base_connector_.creation_strategy ();
+ return this->base_connector_.close ();
+}
+
+int
+TAO_SHMIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
+{
+ if (endpoint->tag () != TAO_TAG_SHMEM_PROFILE)
+ return -1;
+
+ TAO_SHMIOP_Endpoint *shmiop_endpoint =
+ dynamic_cast <TAO_SHMIOP_Endpoint *>(endpoint);
+ if (shmiop_endpoint == 0)
+ return -1;
+
+ const ACE_INET_Addr &remote_address =
+ shmiop_endpoint->object_addr ();
+
+ // Verify that the remote ACE_INET_Addr was initialized properly.
+ // Failure can occur if hostname lookup failed when initializing the
+ // remote ACE_INET_Addr.
+ if (remote_address.get_type () != AF_INET)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) SHMIOP connection failed.\n")
+ ACE_TEXT ("TAO (%P|%t) This is most likely ")
+ ACE_TEXT ("due to a hostname lookup ")
+ ACE_TEXT ("failure.\n")));
+ }
+
+ return -1;
+ }
+
+ return 0;
+
+}
+
+TAO_Transport *
+TAO_SHMIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *,
+ TAO_Transport_Descriptor_Interface &desc,
+ ACE_Time_Value *timeout)
+{
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - SHMIOP_Connector::make_connection, ")
+ ACE_TEXT ("looking for SHMIOP connection.\n")));
+
+ TAO_SHMIOP_Endpoint *shmiop_endpoint =
+ this->remote_endpoint (desc.endpoint ());
+
+ if (shmiop_endpoint == 0)
+ return 0;
+
+ const ACE_INET_Addr &remote_address =
+ shmiop_endpoint->object_addr ();
+
+ if (TAO_debug_level > 2)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - SHMIOP_Connector::make_connection, "
+ "making a new connection to <%C:%d>\n",
+ shmiop_endpoint->host (),
+ shmiop_endpoint->port ()));
+
+ // Get the right synch options
+ ACE_Synch_Options synch_options;
+
+ this->active_connect_strategy_->synch_options (timeout,
+ synch_options);
+
+ TAO_SHMIOP_Connection_Handler *svc_handler = 0;
+
+ // Connect.
+ int result = this->base_connector_.connect (svc_handler,
+ remote_address,
+ synch_options);
+
+ // Make sure that we always do a remove_reference
+ ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler);
+
+ // In case of errors.
+ if (result == -1)
+ {
+ // Give users a clue to the problem.
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) - SHMIOP_Connector::make_connection, ")
+ ACE_TEXT ("connection to <%C:%u> failed (%p)\n"),
+ shmiop_endpoint->host (),
+ shmiop_endpoint->port (),
+ ACE_TEXT ("errno")));
+ }
+
+ return 0;
+ }
+
+ if (svc_handler->keep_waiting ())
+ {
+ svc_handler->connection_pending ();
+ }
+
+ if (svc_handler->error_detected ())
+ {
+ svc_handler->cancel_pending_connection ();
+ }
+
+ TAO_Transport *transport =
+ svc_handler->transport ();
+
+ // At this point, the connection has be successfully connected.
+ // #REFCOUNT# is one.
+ if (TAO_debug_level > 2)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - SHMIOP_Connector::make_connection, "
+ "new %C connection to <%C:%d> on Transport[%d]\n",
+ transport->is_connected() ? "connected" : "not connected",
+ shmiop_endpoint->host (),
+ shmiop_endpoint->port (),
+ svc_handler->peer ().get_handle ()));
+
+ // Add the handler to Cache
+ int retval =
+ this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc,
+ transport);
+
+ // Failure in adding to cache.
+ if (retval == -1)
+ {
+ // Close the handler.
+ svc_handler->close ();
+
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT("TAO (%P|%t) - SHMIOP_Connector::make_connection, ")
+ ACE_TEXT("could not add the new connection to cache\n")));
+ }
+
+ return 0;
+ }
+
+ if (svc_handler->error_detected ())
+ {
+ svc_handler->cancel_pending_connection ();
+ transport->purge_entry();
+ return 0;
+ }
+
+ if (transport->is_connected () &&
+ transport->wait_strategy ()->register_handler () != 0)
+ {
+ // Registration failures.
+
+ // Purge from the connection cache, if we are not in the cache, this
+ // just does nothing.
+ (void) transport->purge_entry ();
+
+ // Close the handler.
+ (void) transport->close_connection ();
+
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) - SHMIOP_Connector [%d]::make_connection, "
+ "could not register the transport in the reactor.\n",
+ transport->id ()));
+
+ return 0;
+ }
+
+ svc_handler_auto_ptr.release ();
+ return transport;
+}
+
+TAO_Profile *
+TAO_SHMIOP_Connector::create_profile (TAO_InputCDR& cdr)
+{
+ TAO_Profile *pfile = 0;
+ ACE_NEW_RETURN (pfile,
+ TAO_SHMIOP_Profile (this->orb_core ()),
+ 0);
+
+ int r = pfile->decode (cdr);
+ if (r == -1)
+ {
+ pfile->_decr_refcnt ();
+ pfile = 0;
+ }
+
+ return pfile;
+}
+
+TAO_Profile *
+TAO_SHMIOP_Connector::make_profile (void)
+{
+ // The endpoint should be of the form:
+ // N.n@port/object_key
+ // or:
+ // port/object_key
+
+ TAO_Profile *profile = 0;
+ ACE_NEW_THROW_EX (profile,
+ TAO_SHMIOP_Profile (this->orb_core ()),
+ CORBA::NO_MEMORY (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+
+ return profile;
+}
+
+int
+TAO_SHMIOP_Connector::check_prefix (const char *endpoint)
+{
+ // Check for a valid string
+ if (!endpoint || !*endpoint)
+ return -1; // Failure
+
+ const char *protocol[] = { "shmiop", "shmioploc" };
+
+ size_t slot = ACE_OS::strchr (endpoint, ':') - endpoint;
+
+ size_t len0 = ACE_OS::strlen (protocol[0]);
+ size_t len1 = ACE_OS::strlen (protocol[1]);
+
+ // Check for the proper prefix in the IOR. If the proper prefix
+ // isn't in the IOR then it is not an IOR we can use.
+ if (slot == len0
+ && ACE_OS::strncasecmp (endpoint, protocol[0], len0) == 0)
+ return 0;
+ else if (slot == len1
+ && ACE_OS::strncasecmp (endpoint, protocol[1], len1) == 0)
+ return 0;
+
+ return -1;
+ // Failure: not an SHMIOP IOR
+ // DO NOT throw an exception here.
+}
+
+char
+TAO_SHMIOP_Connector::object_key_delimiter (void) const
+{
+ return TAO_SHMIOP_Profile::object_key_delimiter_;
+}
+
+TAO_SHMIOP_Endpoint *
+TAO_SHMIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint)
+{
+ if (endpoint->tag () != TAO_TAG_SHMEM_PROFILE)
+ return 0;
+
+ TAO_SHMIOP_Endpoint *shmiop_endpoint =
+ dynamic_cast <TAO_SHMIOP_Endpoint *>(endpoint);
+ if (shmiop_endpoint == 0)
+ return 0;
+
+ return shmiop_endpoint;
+}
+
+int
+TAO_SHMIOP_Connector::cancel_svc_handler (
+ TAO_Connection_Handler * svc_handler)
+{
+ TAO_SHMIOP_Connection_Handler* handler=
+ dynamic_cast<TAO_SHMIOP_Connection_Handler*>(svc_handler);
+
+ if (handler)
+ // Cancel from the connector
+ return this->base_connector_.cancel (handler);
+
+ return -1;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_SHMIOP && TAO_HAS_SHMIOP != 0 */