summaryrefslogtreecommitdiff
path: root/TAO/tao/Invocation_Adapter.cpp
diff options
context:
space:
mode:
authorWilliam R. Otte <wotte@dre.vanderbilt.edu>2006-07-24 15:50:21 +0000
committerWilliam R. Otte <wotte@dre.vanderbilt.edu>2006-07-24 15:50:21 +0000
commit3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c (patch)
tree197c810e5f5bce17b1233a7cb8d7b50c0bcd25e2 /TAO/tao/Invocation_Adapter.cpp
parent6b846cf03c0bcbd8c276cb0af61a181e5f98eaae (diff)
downloadATCD-3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c.tar.gz
Repo restructuring
Diffstat (limited to 'TAO/tao/Invocation_Adapter.cpp')
-rw-r--r--TAO/tao/Invocation_Adapter.cpp421
1 files changed, 421 insertions, 0 deletions
diff --git a/TAO/tao/Invocation_Adapter.cpp b/TAO/tao/Invocation_Adapter.cpp
new file mode 100644
index 00000000000..39ac727b340
--- /dev/null
+++ b/TAO/tao/Invocation_Adapter.cpp
@@ -0,0 +1,421 @@
+//$Id$
+
+#include "tao/Invocation_Adapter.h"
+#include "tao/Profile_Transport_Resolver.h"
+#include "tao/operation_details.h"
+#include "tao/Stub.h"
+#include "tao/ORB_Core.h"
+#include "tao/Synch_Invocation.h"
+#include "tao/debug.h"
+#include "tao/Collocated_Invocation.h"
+#include "tao/Transport.h"
+#include "tao/Transport_Mux_Strategy.h"
+#include "tao/Collocation_Proxy_Broker.h"
+#include "tao/GIOP_Utils.h"
+#if !defined (__ACE_INLINE__)
+# include "tao/Invocation_Adapter.inl"
+#endif /* __ACE_INLINE__ */
+
+
+ACE_RCSID (tao,
+ Invocation_Adapter,
+ "$Id$")
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ Invocation_Adapter::~Invocation_Adapter (void)
+ {
+ }
+
+ void
+ Invocation_Adapter::invoke (TAO::Exception_Data *ex_data,
+ unsigned long ex_count
+ ACE_ENV_ARG_DECL)
+ {
+ // Should stub object be refcounted here?
+ TAO_Stub *stub =
+ this->get_stub (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ TAO_Operation_Details op_details (this->operation_,
+ this->op_len_,
+ this->number_args_ > 1,
+ this->args_,
+ this->number_args_,
+ ex_data,
+ ex_count);
+
+ this->invoke_i (stub,
+ op_details
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ void
+ Invocation_Adapter::invoke_i (TAO_Stub *stub,
+ TAO_Operation_Details &details
+ ACE_ENV_ARG_DECL)
+ {
+ // Cache the target to a local variable.
+ CORBA::Object_var effective_target =
+ CORBA::Object::_duplicate (this->target_);
+
+ // Initial state
+ TAO::Invocation_Status status = TAO_INVOKE_START;
+
+ ACE_Time_Value *max_wait_time = 0;
+
+ while (status == TAO_INVOKE_START ||
+ status == TAO_INVOKE_RESTART)
+ {
+ // Default we go to remote
+ Collocation_Strategy strat = TAO_CS_REMOTE_STRATEGY;
+
+ // If we have a collocated proxy broker we look if we maybe
+ // can use a collocated invocation. Similarly, if the
+ // target object reference contains a pointer to a servant,
+ // the object reference also refers to a collocated object.
+ if (cpb_ != 0 || effective_target->_servant () != 0)
+ {
+ strat =
+ TAO_ORB_Core::collocation_strategy (effective_target.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ if (strat == TAO_CS_REMOTE_STRATEGY ||
+ strat == TAO_CS_LAST)
+ {
+ status =
+ this->invoke_remote_i (stub,
+ details,
+ effective_target,
+ max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ else
+ {
+ if (strat == TAO_CS_THRU_POA_STRATEGY)
+ {
+ (void) this->set_response_flags (stub,
+ details);
+ }
+
+ status =
+ this->invoke_collocated_i (stub,
+ details,
+ effective_target,
+ strat
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ if (status == TAO_INVOKE_RESTART)
+ {
+ details.reset_request_service_info ();
+ details.reset_reply_service_info ();
+
+ if (TAO_debug_level > 2)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - Invocation_Adapter::invoke_i, "
+ "handling forwarded locations \n"));
+ }
+ }
+ }
+ }
+
+ bool
+ Invocation_Adapter::get_timeout (TAO_Stub *stub,
+ ACE_Time_Value &timeout)
+ {
+ bool has_timeout = false;
+ this->target_->orb_core ()->call_timeout_hook (stub,
+ has_timeout,
+ timeout);
+
+ return has_timeout;
+ }
+
+ TAO_Stub *
+ Invocation_Adapter::get_stub (ACE_ENV_SINGLE_ARG_DECL) const
+ {
+ TAO_Stub * const stub =
+ this->target_->_stubobj ();
+
+ if (stub == 0)
+ ACE_THROW_RETURN (CORBA::INTERNAL (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ EINVAL),
+ CORBA::COMPLETED_NO),
+ stub);
+
+ return stub;
+ }
+
+ Invocation_Status
+ Invocation_Adapter::invoke_collocated_i (TAO_Stub *stub,
+ TAO_Operation_Details &details,
+ CORBA::Object_var &effective_target,
+ Collocation_Strategy strat
+ ACE_ENV_ARG_DECL)
+ {
+ // To make a collocated call we must have a collocated proxy broker, the
+ // invoke_i() will make sure that we only come here when we have one
+ ACE_ASSERT (cpb_ != 0
+ || (strat == TAO_CS_THRU_POA_STRATEGY
+ && effective_target->_servant () != 0));
+
+ // Initial state
+ TAO::Invocation_Status status = TAO_INVOKE_START;
+
+ Collocated_Invocation coll_inv (this->target_,
+ effective_target.in (),
+ stub,
+ details,
+ this->type_ == TAO_TWOWAY_INVOCATION);
+
+ status =
+ coll_inv.invoke (this->cpb_,
+ strat
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
+
+ if (status == TAO_INVOKE_RESTART &&
+ coll_inv.is_forwarded ())
+ {
+ effective_target =
+ coll_inv.steal_forwarded_reference ();
+
+#if TAO_HAS_INTERCEPTORS == 1
+ const bool is_permanent_forward =
+ (coll_inv.reply_status() == TAO_GIOP_LOCATION_FORWARD_PERM);
+#else
+ const bool is_permanent_forward = false;
+#endif
+
+ (void) this->object_forwarded (effective_target,
+ stub,
+ is_permanent_forward
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
+ }
+
+ return status;
+ }
+
+ void
+ Invocation_Adapter::set_response_flags (
+ TAO_Stub *stub,
+ TAO_Operation_Details &details)
+ {
+ switch (this->type_)
+ {
+ case TAO_ONEWAY_INVOCATION:
+ {
+ // Grab the syncscope policy from the ORB.
+ Messaging::SyncScope sync_scope;
+
+ bool has_synchronization = false;
+
+ stub->orb_core ()->call_sync_scope_hook (stub,
+ has_synchronization,
+ sync_scope);
+ if (has_synchronization)
+ details.response_flags (CORBA::Octet (sync_scope));
+ else
+ details.response_flags (
+ CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT));
+ break;
+ }
+ case TAO_TWOWAY_INVOCATION:
+ {
+ // @@note: Need to change this to something better. Too many
+ // hash defines meaning the same things.
+ details.response_flags (TAO_TWOWAY_RESPONSE_FLAG);
+ break;
+ }
+ }
+
+ return;
+ }
+
+ Invocation_Status
+ Invocation_Adapter::invoke_remote_i (TAO_Stub *stub,
+ TAO_Operation_Details &details,
+ CORBA::Object_var &effective_target,
+ ACE_Time_Value *&max_wait_time
+ ACE_ENV_ARG_DECL)
+ {
+ ACE_Time_Value tmp_wait_time;
+ bool is_timeout =
+ this->get_timeout (stub,
+ tmp_wait_time);
+
+ if (is_timeout)
+ max_wait_time = &tmp_wait_time;
+
+ (void) this->set_response_flags (stub,
+ details);
+
+ // Create the resolver which will pick (or create) for us a
+ // transport and a profile from the effective_target.
+ Profile_Transport_Resolver resolver (
+ effective_target.in (),
+ stub,
+ (details.response_flags () != Messaging::SYNC_NONE));
+
+ resolver.resolve (max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
+
+ // Update the request id now that we have a transport
+ details.request_id (resolver.transport ()->tms ()->request_id ());
+
+ if (this->type_ == TAO_ONEWAY_INVOCATION)
+ {
+ return this->invoke_oneway (details,
+ effective_target,
+ resolver,
+ max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ }
+ else if (this->type_ == TAO_TWOWAY_INVOCATION)
+ {
+ return this->invoke_twoway (details,
+ effective_target,
+ resolver,
+ max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ }
+
+ return TAO_INVOKE_FAILURE;
+ }
+
+ Invocation_Status
+ Invocation_Adapter::invoke_twoway (TAO_Operation_Details &details,
+ CORBA::Object_var &effective_target,
+ Profile_Transport_Resolver &r,
+ ACE_Time_Value *&max_wait_time
+ ACE_ENV_ARG_DECL)
+ {
+ // Simple sanity check
+ if (this->mode_ != TAO_SYNCHRONOUS_INVOCATION ||
+ this->type_ != TAO_TWOWAY_INVOCATION)
+ {
+ ACE_THROW_RETURN (CORBA::INTERNAL (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ EINVAL),
+ CORBA::COMPLETED_NO),
+ TAO_INVOKE_FAILURE);
+ }
+
+ TAO::Synch_Twoway_Invocation synch (this->target_,
+ r,
+ details);
+
+ Invocation_Status status =
+ synch.remote_twoway (max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
+
+ if (status == TAO_INVOKE_RESTART &&
+ synch.is_forwarded ())
+ {
+ effective_target =
+ synch.steal_forwarded_reference ();
+
+#if TAO_HAS_INTERCEPTORS == 1
+ const bool is_permanent_forward =
+ (synch.reply_status() == TAO_GIOP_LOCATION_FORWARD_PERM);
+#else
+ const bool is_permanent_forward = false;
+#endif
+
+ this->object_forwarded (effective_target,
+ r.stub (),
+ is_permanent_forward
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
+ }
+
+ return status;
+ }
+
+ Invocation_Status
+ Invocation_Adapter::invoke_oneway (TAO_Operation_Details &details,
+ CORBA::Object_var &effective_target,
+ Profile_Transport_Resolver &r,
+ ACE_Time_Value *&max_wait_time
+ ACE_ENV_ARG_DECL)
+ {
+ TAO::Synch_Oneway_Invocation synch (this->target_,
+ r,
+ details);
+
+ Invocation_Status s =
+ synch.remote_oneway (max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
+
+ if (s == TAO_INVOKE_RESTART &&
+ synch.is_forwarded ())
+ {
+ effective_target =
+ synch.steal_forwarded_reference ();
+
+#if TAO_HAS_INTERCEPTORS == 1
+ const bool is_permanent_forward =
+ (synch.reply_status() == TAO_GIOP_LOCATION_FORWARD_PERM);
+#else
+ const bool is_permanent_forward = false;
+#endif
+ this->object_forwarded (effective_target,
+ r.stub (),
+ is_permanent_forward
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
+ }
+
+ return s;
+ }
+
+ void
+ Invocation_Adapter::object_forwarded (CORBA::Object_var &effective_target,
+ TAO_Stub *stub,
+ CORBA::Boolean permanent_forward
+ ACE_ENV_ARG_DECL)
+ {
+ // The object pointer has to be changed to a TAO_Stub pointer
+ // in order to obtain the profiles.
+ TAO_Stub *stubobj =
+ effective_target->_stubobj ();
+
+ if (stubobj == 0)
+ ACE_THROW (CORBA::INTERNAL (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
+ errno),
+ CORBA::COMPLETED_NO));
+
+
+ // Reset the profile in the stubs
+ stub->add_forward_profiles (stubobj->base_profiles (), permanent_forward);
+
+ if (stub->next_profile () == 0)
+ ACE_THROW (CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
+ errno),
+ CORBA::COMPLETED_NO));
+
+ return;
+ }
+} // End namespace TAO
+
+TAO_END_VERSIONED_NAMESPACE_DECL