summaryrefslogtreecommitdiff
path: root/TAO/tao/Strategies/Optimized_Connection_Endpoint_Selector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/Strategies/Optimized_Connection_Endpoint_Selector.cpp')
-rw-r--r--TAO/tao/Strategies/Optimized_Connection_Endpoint_Selector.cpp178
1 files changed, 178 insertions, 0 deletions
diff --git a/TAO/tao/Strategies/Optimized_Connection_Endpoint_Selector.cpp b/TAO/tao/Strategies/Optimized_Connection_Endpoint_Selector.cpp
new file mode 100644
index 00000000000..5b0938be1df
--- /dev/null
+++ b/TAO/tao/Strategies/Optimized_Connection_Endpoint_Selector.cpp
@@ -0,0 +1,178 @@
+// -*- C++ -*-
+
+#include "tao/Strategies/Optimized_Connection_Endpoint_Selector.h"
+
+#include "tao/debug.h"
+#include "tao/Stub.h"
+#include "tao/Profile.h"
+#include "tao/Endpoint.h"
+#include "tao/Base_Transport_Property.h"
+#include "tao/ORB_Core.h"
+#include "tao/Transport.h"
+#include "tao/Profile_Transport_Resolver.h"
+
+ACE_RCSID (tao,
+ Optimized_Connection_Endpoint_Selector,
+ "$Id$")
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+// ****************************************************************
+
+ACE_Time_Value TAO_Optimized_Connection_Endpoint_Selector::timeout_;
+
+TAO_Optimized_Connection_Endpoint_Selector::TAO_Optimized_Connection_Endpoint_Selector (const ACE_Time_Value &tv)
+{
+ TAO_Optimized_Connection_Endpoint_Selector::timeout_ = tv;
+ if (TAO_debug_level)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO(%P|%t) Optimized Connection Enpoint Selector: ")
+ ACE_TEXT ("Initializing timeout hook tv = %d sec, %d usec\n"),
+ tv.sec(), tv.usec()));
+ }
+ if (tv > ACE_Time_Value::zero)
+ {
+ TAO_ORB_Core::connection_timeout_hook
+ (TAO_Optimized_Connection_Endpoint_Selector::hook);
+ }
+}
+
+TAO_Optimized_Connection_Endpoint_Selector::~TAO_Optimized_Connection_Endpoint_Selector (void)
+{
+}
+
+
+void
+TAO_Optimized_Connection_Endpoint_Selector::hook (TAO_ORB_Core *,
+ TAO_Stub *,
+ bool &has_timeout,
+ ACE_Time_Value &tv)
+{
+ has_timeout =
+ TAO_Optimized_Connection_Endpoint_Selector::
+ timeout_ > ACE_Time_Value::zero;
+ if (has_timeout)
+ tv = TAO_Optimized_Connection_Endpoint_Selector::timeout_;
+}
+
+int
+TAO_Optimized_Connection_Endpoint_Selector::check_profile (TAO_Profile *p,
+ TAO::Profile_Transport_Resolver *r)
+{
+ TAO_Endpoint *effective_endpoint = 0;
+
+ r->profile(p);
+ effective_endpoint = p->endpoint ();
+ size_t endpoint_count = p->endpoint_count();
+ for (size_t i = 0; i < endpoint_count; ++i)
+ {
+ TAO_Base_Transport_Property desc (effective_endpoint);
+ if (r->find_transport(&desc))
+ return 1;
+ // Go to the next endpoint in this profile
+ effective_endpoint = effective_endpoint->next();
+ }
+ return 0;
+}
+
+void
+TAO_Optimized_Connection_Endpoint_Selector::select_endpoint
+ ( TAO::Profile_Transport_Resolver *r,
+ ACE_Time_Value *max_wait_time
+ ACE_ENV_ARG_DECL)
+{
+ TAO_Stub *stub = r->stub();
+ TAO_Profile *p = stub->profile_in_use();
+
+ // first, look for the endpoints for the current profile in use.
+ // if that is available then go for it.
+
+ if (this->check_profile (p, r) != 0)
+ return;
+
+ // next, look for any other profiles. If the stub has any forward profiles,
+ // use those, otherwise look at the base profiles. This separation is
+ // necessary to avoid re-using a corbaloc or other previously forwarded
+ // profile.
+
+ const TAO_MProfile *profiles = stub->forward_profiles();
+ if (profiles != 0)
+ {
+ for (CORBA::ULong count = 0; count < profiles->profile_count(); count++)
+ {
+ p = const_cast<TAO_Profile *>(profiles->get_profile(count));
+ if (this->check_profile (p, r) != 0)
+ {
+ if (stub->profile_in_use() != p)
+ {
+ // thread-safe way to coerse stub to this profile.
+ stub->reset_profiles();
+ while (stub->profile_in_use() != p)
+ if (stub->next_profile_retry() == 0)
+ break;
+ }
+ return;
+ }
+ }
+ }
+ else
+ {
+ do
+ {
+ p = stub->profile_in_use();
+ if (this->check_profile(p, r) != 0)
+ return;
+ }
+ while (stub->next_profile_retry () != 0);
+ }
+
+
+
+ // at this point, we do not have an existing transport, so we must
+ // reset the profile list and try establishing connections via the
+ // connector(s).
+
+ do
+ {
+ r->profile (r->stub ()->profile_in_use ());
+
+ // Check whether we need to do a blocked wait or we have a
+ // non-blocked wait and we support that. If this is not the
+ // case we can't use this profile so try the next.
+ if (r->blocked_connect () ||
+ (!r->blocked_connect () && r->profile ()->supports_non_blocking_oneways ()))
+ {
+ const size_t endpoint_count =
+ r->profile ()->endpoint_count ();
+
+ TAO_Endpoint *ep =
+ r->profile ()->endpoint ();
+
+ for (size_t i = 0; i < endpoint_count; ++i)
+ {
+ TAO_Base_Transport_Property desc (ep);
+ const bool retval =
+ r->try_connect (&desc,
+ max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Check if the connect has completed.
+ if (retval)
+ return;
+
+ // Go to the next endpoint in this profile.
+ ep = ep->next ();
+ }
+ }
+ }
+ while (r->stub ()->next_profile_retry () != 0);
+
+ // If we get here, we completely failed to find an endpoint selector
+ // that we know how to use, so throw an exception.
+ ACE_THROW (CORBA::TRANSIENT (CORBA::OMGVMCID | 2,
+ CORBA::COMPLETED_NO));
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL