summaryrefslogtreecommitdiff
path: root/trunk/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp')
-rw-r--r--trunk/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp216
1 files changed, 216 insertions, 0 deletions
diff --git a/trunk/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp b/trunk/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
new file mode 100644
index 00000000000..f0ef8094e34
--- /dev/null
+++ b/trunk/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
@@ -0,0 +1,216 @@
+//$Id$
+#include "tao/Messaging/Asynch_Invocation_Adapter.h"
+#include "tao/Messaging/Asynch_Reply_Dispatcher.h"
+#include "tao/Messaging/Asynch_Invocation.h"
+
+#include "tao/Profile_Transport_Resolver.h"
+#include "tao/operation_details.h"
+#include "tao/Stub.h"
+#include "tao/Transport.h"
+#include "tao/Muxed_TMS.h"
+#include "tao/ORB_Constants.h"
+#include "tao/debug.h"
+#include "tao/ORB_Core.h"
+#include "tao/Thread_Lane_Resources.h"
+#include "tao/GIOP_Utils.h"
+
+
+ACE_RCSID (Messaging,
+ Asynch_Invocation_Adapter,
+ "$Id$")
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ Asynch_Invocation_Adapter::Asynch_Invocation_Adapter (
+ CORBA::Object *target,
+ Argument **args,
+ int arg_number,
+ const char *operation,
+ size_t op_len,
+ Collocation_Proxy_Broker *p,
+ Invocation_Mode m)
+ : Invocation_Adapter (target,
+ args,
+ arg_number,
+ operation,
+ op_len,
+ p,
+ TAO_TWOWAY_INVOCATION,
+ m)
+ , safe_rd_ ()
+ {
+ }
+
+ void
+ Asynch_Invocation_Adapter::invoke (
+ Messaging::ReplyHandler_ptr reply_handler_ptr,
+ const TAO_Reply_Handler_Skeleton &reply_handler_skel
+ ACE_ENV_ARG_DECL)
+ {
+ TAO_Stub * stub =
+ this->get_stub (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (TAO_debug_level >= 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_Messaging (%P|%t) - Asynch_Invocation_Adapter::"
+ "invoke\n"));
+ }
+
+ // If the reply handler is nil, we do not create a reply dispatcher.
+ // The ORB will drop replies to which it cannot associate a reply
+ // dispatcher.
+ if (!CORBA::is_nil (reply_handler_ptr))
+ {
+ // New reply dispatcher on the heap or allocator, because
+ // we will go out of scope and hand over the reply dispatcher
+ // to the ORB.
+
+ TAO_Asynch_Reply_Dispatcher *rd = 0;
+
+ // Get the allocator we could use.
+ ACE_Allocator* ami_allocator =
+ stub->orb_core ()->lane_resources().ami_response_handler_allocator();
+
+ // If we have an allocator, use it, else use the heap.
+ if (ami_allocator)
+ {
+ ACE_NEW_MALLOC (
+ rd,
+ static_cast<TAO_Asynch_Reply_Dispatcher *> (
+ ami_allocator->malloc (sizeof (TAO_Asynch_Reply_Dispatcher))),
+ TAO_Asynch_Reply_Dispatcher (reply_handler_skel,
+ reply_handler_ptr,
+ stub->orb_core (),
+ ami_allocator));
+ }
+ else
+ {
+ ACE_NEW (rd,
+ TAO_Asynch_Reply_Dispatcher (reply_handler_skel,
+ reply_handler_ptr,
+ stub->orb_core (),
+ 0));
+ }
+
+ if (rd == 0)
+ {
+ ACE_THROW (CORBA::NO_MEMORY ());
+ }
+
+ this->safe_rd_.reset (rd);
+ }
+
+ Invocation_Adapter::invoke (0, 0 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ void
+ Asynch_Invocation_Adapter::invoke (
+ TAO::Exception_Data *ex,
+ unsigned long ex_count
+ ACE_ENV_ARG_DECL)
+ {
+ Invocation_Adapter::invoke (ex, ex_count ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ Invocation_Status
+ Asynch_Invocation_Adapter::invoke_collocated_i (
+ TAO_Stub *stub,
+ TAO_Operation_Details &details,
+ CORBA::Object_var &effective_target,
+ Collocation_Strategy strat
+ ACE_ENV_ARG_DECL)
+ {
+ // When doing a collocation asynch invocation we shouldn't use the
+ // stub args but use the skel args
+ details.use_stub_args (false);
+
+ return Invocation_Adapter::invoke_collocated_i (stub,
+ details,
+ effective_target,
+ strat
+ ACE_ENV_ARG_PARAMETER);
+ }
+
+ Invocation_Status
+ Asynch_Invocation_Adapter::invoke_twoway (
+ TAO_Operation_Details &op,
+ 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_ASYNCHRONOUS_CALLBACK_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);
+ }
+
+ if (this->safe_rd_.get ())
+ {
+ // Cache the transport in the reply dispatcher
+ this->safe_rd_->transport (r.transport ());
+
+ // AMI Timeout Handling Begin
+ ACE_Time_Value tmp;
+
+ if (this->get_timeout (r.stub (),
+ tmp))
+ {
+ this->safe_rd_->schedule_timer (
+ op.request_id (),
+ *max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
+ }
+ }
+
+ // Loose ownership of the reply dispatcher
+ TAO::Asynch_Remote_Invocation asynch (
+ effective_target.in (),
+ r,
+ op,
+ this->safe_rd_.release ());
+
+ Invocation_Status const s =
+ asynch.remote_invocation (max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
+
+ if (s == TAO_INVOKE_RESTART &&
+ asynch.is_forwarded ())
+ {
+ effective_target = asynch.steal_forwarded_reference ();
+
+#if TAO_HAS_INTERCEPTORS == 1
+ CORBA::Boolean const permanent_forward =
+ (asynch.reply_status() == TAO_GIOP_LOCATION_FORWARD_PERM);
+#else
+ CORBA::Boolean const permanent_forward = false;
+#endif
+
+ this->object_forwarded (effective_target,
+ r.stub (),
+ permanent_forward
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
+ }
+
+ return s;
+ }
+
+} // End namespace TAO
+
+TAO_END_VERSIONED_NAMESPACE_DECL