summaryrefslogtreecommitdiff
path: root/TAO/tao/Invocation_Adapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/Invocation_Adapter.cpp')
-rw-r--r--TAO/tao/Invocation_Adapter.cpp220
1 files changed, 220 insertions, 0 deletions
diff --git a/TAO/tao/Invocation_Adapter.cpp b/TAO/tao/Invocation_Adapter.cpp
new file mode 100644
index 00000000000..8f0628f52c1
--- /dev/null
+++ b/TAO/tao/Invocation_Adapter.cpp
@@ -0,0 +1,220 @@
+//$Id$
+#include "Invocation_Adapter.h"
+#include "Object.h"
+#include "Profile_Transport_Resolver.h"
+#include "operation_details.h"
+#include "Stub.h"
+#include "ORB_Core.h"
+//@@ Need to remove when we take care of the note below.
+#include "corbafwd.h"
+#include "Synch_Invocation.h"
+#include "Collocated_Invocation.h"
+#include "Transport.h"
+#include "Transport_Mux_Strategy.h"
+#include "Messaging_SyncScopeC.h"
+#include "Collocation_Proxy_Broker.h"
+
+ACE_RCSID (tao,
+ Invocation_Adapter,
+ "$Id$")
+
+
+namespace TAO
+{
+ Invocation_Adapter::Invocation_Adapter (CORBA::Object *target,
+ Argument **args,
+ int arg_number,
+ char *operation,
+ int op_len,
+ Collocation_Proxy_Broker *p,
+ Invocation_Type type,
+ Invocation_Mode mode)
+ : target_ (target)
+ , args_ (args)
+ , number_args_ (arg_number)
+ , operation_ (operation)
+ , op_len_ (op_len)
+ , cpb_ (p)
+ , type_ (type)
+ , mode_ (mode)
+ {
+ }
+
+
+ void
+ Invocation_Adapter::invoke (TAO_Exception_Data *ex_data,
+ unsigned long ex_count
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ // Should stub object be refcounted here?
+ TAO_Stub *stub =
+ this->target_->_stubobj ();
+
+ if (stub == 0)
+ ACE_THROW (CORBA::INTERNAL (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_DEFAULT_MINOR_CODE,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+
+ TAO_Operation_Details op_details (this->operation_,
+ this->op_len_,
+ this->number_args_ != 0,
+ this->args_,
+ this->number_args_,
+ ex_data,
+ ex_count);
+ if (this->cpb_)
+ {
+ this->invoke_collocated (stub,
+ op_details
+ ACE_ENV_ARG_DECL);
+ ACE_CHECK;
+
+ return;
+ }
+
+ this->invoke_remote (stub,
+ op_details
+ ACE_ENV_ARG_DECL);
+ ACE_CHECK;
+ }
+
+ void
+ Invocation_Adapter::invoke_collocated (TAO_Stub *stub,
+ TAO_Operation_Details &details
+ ACE_ENV_ARG_DECL)
+ {
+ CORBA::Object *local_target = this->target_;
+
+ // Initial state
+ TAO::Invocation_Status status = TAO_INVOKE_START;
+
+ while (status == TAO_INVOKE_START ||
+ status == TAO_INVOKE_RESTART)
+ {
+ Collocation_Strategy strat =
+ this->cpb_->get_strategy (local_target
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (strat == TAO_CS_REMOTE_STRATEGY ||
+ strat == TAO_CS_LAST)
+ {
+ this->invoke_remote (stub,
+ details
+ ACE_ENV_ARG_PARAMETER);
+
+ ACE_CHECK;
+
+ return;
+ }
+
+ Collocated_Invocation coll_inv (stub,
+ details);
+
+ status = coll_inv.invoke (this->cpb_,
+ local_target,
+ strat
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (status == TAO_INVOKE_RESTART)
+ local_target = coll_inv.steal_forwarded_reference ();
+ }
+ }
+
+ void
+ Invocation_Adapter::invoke_remote (TAO_Stub *stub,
+ TAO_Operation_Details &op
+ ACE_ENV_ARG_DECL)
+ {
+ CORBA::Object *local_target = this->target_;
+
+ ACE_Time_Value tmp_wait_time;
+ bool is_timeout =
+ this->get_timeout (tmp_wait_time);
+
+ ACE_Time_Value *max_wait_time = 0;
+
+ if (is_timeout)
+ max_wait_time = &tmp_wait_time;
+
+ // Initial state
+ TAO::Invocation_Status status = TAO_INVOKE_START;
+
+ while (status == TAO_INVOKE_START ||
+ status == TAO_INVOKE_RESTART)
+ {
+ Profile_Transport_Resolver resolver (local_target,
+ stub);
+
+ resolver.resolve (max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Update the request id now that we have a transport
+ op.request_id (resolver.transport ()->tms ()->request_id ());
+
+ if (this->type_ == TAO_ONEWAY_INVOCATION)
+ {
+ int has_synchronization = 0;
+ Messaging::SyncScope sync_scope;
+ stub->orb_core ()->call_sync_scope_hook (stub,
+ has_synchronization,
+ sync_scope);
+
+ op.response_flags (sync_scope);
+
+ TAO::Synch_Oneway_Invocation synch (resolver,
+ op);
+
+ status =
+ synch.remote_oneway (max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ else if (this->type_ == TAO_TWOWAY_INVOCATION
+ && this->mode_ == TAO_SYNCHRONOUS_INVOCATION)
+ {
+ // @@ NOTE:Need to change this to something better. Too many
+ // hash defines meaning the same thing..
+ op.response_flags (TAO_TWOWAY_RESPONSE_FLAG);
+ TAO::Synch_Twoway_Invocation synch (resolver,
+ op);
+
+ status =
+ synch.remote_twoway (max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (status == TAO_INVOKE_RESTART)
+ local_target = synch.steal_forwarded_reference ();
+ }
+ else if (this->type_ == TAO_TWOWAY_INVOCATION
+ && this->mode_ == TAO_ASYNCHRONOUS_CALLBACK_INVOCATION)
+ {
+ // Should never get here..
+ ACE_THROW (CORBA::INTERNAL (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_DEFAULT_MINOR_CODE,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+
+ }
+ }
+
+ bool
+ Invocation_Adapter::get_timeout (ACE_Time_Value &timeout)
+ {
+ bool has_timeout;
+ this->target_->orb_core ()->call_timeout_hook (this->target_->_stubobj (),
+ has_timeout,
+ timeout);
+
+ return has_timeout;
+ }
+
+} // End namespace TAO