summaryrefslogtreecommitdiff
path: root/trunk/TAO/tao/DynamicInterface/Request.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/TAO/tao/DynamicInterface/Request.cpp')
-rw-r--r--trunk/TAO/tao/DynamicInterface/Request.cpp338
1 files changed, 338 insertions, 0 deletions
diff --git a/trunk/TAO/tao/DynamicInterface/Request.cpp b/trunk/TAO/tao/DynamicInterface/Request.cpp
new file mode 100644
index 00000000000..34519883c93
--- /dev/null
+++ b/trunk/TAO/tao/DynamicInterface/Request.cpp
@@ -0,0 +1,338 @@
+// $Id$
+
+#include "tao/DynamicInterface/Request.h"
+
+ACE_RCSID (DynamicInterface,
+ Request,
+ "$Id$")
+
+#include "tao/DynamicInterface/DII_Invocation_Adapter.h"
+#include "tao/DynamicInterface/DII_Arguments.h"
+#include "tao/DynamicInterface/Context.h"
+
+#include "tao/AnyTypeCode/NVList.h"
+#include "tao/Object.h"
+#include "tao/Pluggable_Messaging_Utils.h"
+#include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
+
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+
+#if !defined (__ACE_INLINE__)
+# include "tao/DynamicInterface/Request.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+// Reference counting for DII Request object.
+
+CORBA::ULong
+CORBA::Request::_incr_refcnt (void)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ ace_mon,
+ this->lock_,
+ 0);
+
+ return this->refcount_++;
+}
+
+CORBA::ULong
+CORBA::Request::_decr_refcnt (void)
+{
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ ace_mon,
+ this->lock_,
+ 0);
+
+ --this->refcount_;
+
+ if (this->refcount_ != 0)
+ {
+ return this->refcount_;
+ }
+ }
+
+ delete this;
+ return 0;
+}
+
+// DII Request class implementation
+
+CORBA::Request::Request (CORBA::Object_ptr obj,
+ CORBA::ORB_ptr orb,
+ const CORBA::Char *op,
+ CORBA::NVList_ptr args,
+ CORBA::NamedValue_ptr result,
+ CORBA::Flags flags,
+ CORBA::ExceptionList_ptr exceptions
+ ACE_ENV_ARG_DECL_NOT_USED)
+ : target_ (CORBA::Object::_duplicate (obj)),
+ orb_ (CORBA::ORB::_duplicate (orb)),
+ opname_ (CORBA::string_dup (op)),
+ args_ (CORBA::NVList::_duplicate (args)),
+ result_ (CORBA::NamedValue::_duplicate (result)),
+ flags_ (flags),
+ // env_ (env),
+ exceptions_ (CORBA::ExceptionList::_duplicate (exceptions)),
+ contexts_ (0),
+ ctx_ (CORBA::Context::_nil ()),
+ refcount_ (1),
+ lazy_evaluation_ (false),
+ response_received_ (0),
+ byte_order_ (TAO_ENCAP_BYTE_ORDER)
+{
+ if (this->exceptions_.in () == 0)
+ {
+ CORBA::ExceptionList *tmp = 0;
+ ACE_NEW (tmp,
+ CORBA::ExceptionList);
+
+ this->exceptions_ = tmp;
+ }
+}
+
+CORBA::Request::Request (CORBA::Object_ptr obj,
+ CORBA::ORB_ptr orb,
+ const CORBA::Char *op
+ ACE_ENV_ARG_DECL_NOT_USED)
+ : target_ (CORBA::Object::_duplicate (obj)),
+ orb_ (CORBA::ORB::_duplicate (orb)),
+ opname_ (CORBA::string_dup (op)),
+ flags_ (0),
+ // env_ (env),
+ contexts_ (0),
+ ctx_ (CORBA::Context::_nil ()),
+ refcount_ (1),
+ lazy_evaluation_ (false),
+ response_received_ (0),
+ byte_order_ (TAO_ENCAP_BYTE_ORDER)
+{
+ CORBA::ExceptionList *tmp = 0;
+ ACE_NEW (tmp,
+ CORBA::ExceptionList);
+
+ this->exceptions_ = tmp;
+
+ ACE_NEW (this->args_,
+ CORBA::NVList);
+
+ ACE_NEW (this->result_,
+ CORBA::NamedValue);
+}
+
+CORBA::Request::~Request (void)
+{
+ ACE_ASSERT (refcount_ == 0);
+
+ ::CORBA::release (this->target_);
+ ::CORBA::string_free ((char*) this->opname_);
+ this->opname_ = 0;
+ ::CORBA::release (this->args_);
+ ::CORBA::release (this->result_);
+}
+
+// The public DII interfaces: normal and oneway calls.
+//
+// NOTE that using DII, programmers can get the special behaviour of
+// discarding the response for normal calls. This doesn't change the
+// semantics of any OMG-IDL interface, it just streamlines control
+// flow in some exotic situations.
+
+void
+CORBA::Request::invoke (ACE_ENV_SINGLE_ARG_DECL)
+{
+ TAO::NamedValue_Argument _tao_retval (this->result_);
+
+ TAO::NVList_Argument _tao_in_list (this->args_,
+ this->lazy_evaluation_);
+
+ TAO::Argument *_tao_arg_list [] = {
+ &_tao_retval,
+ &_tao_in_list
+ };
+
+ TAO::DII_Invocation_Adapter _tao_call (
+ this->target_,
+ _tao_arg_list,
+ sizeof( _tao_arg_list ) / sizeof( TAO::Argument* ),
+ this->opname_,
+ static_cast<CORBA::ULong> (ACE_OS::strlen (this->opname_)),
+ this->exceptions_.in (),
+ this);
+
+ _tao_call.invoke (0,
+ 0
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // If this request was created by a gateway, then result_
+ // and/or args_ are shared by a CORBA::ServerRequest, whose
+ // reply must be in the same byte order as the reply we are
+ // handling here. So we set the member to be accessed later.
+ this->byte_order_ = _tao_retval.byte_order ();
+}
+
+void
+CORBA::Request::send_oneway (ACE_ENV_SINGLE_ARG_DECL)
+{
+ TAO::NamedValue_Argument _tao_retval (this->result_);
+
+ TAO::NVList_Argument _tao_in_list (this->args_,
+ this->lazy_evaluation_);
+
+ TAO::Argument *_tao_arg_list [] = {
+ &_tao_retval,
+ &_tao_in_list
+ };
+
+ TAO::Invocation_Adapter _tao_call (
+ this->target_,
+ _tao_arg_list,
+ sizeof( _tao_arg_list ) / sizeof( TAO::Argument* ),
+ this->opname_,
+ static_cast<CORBA::ULong> (ACE_OS::strlen (this->opname_)),
+ 0,
+ TAO::TAO_ONEWAY_INVOCATION,
+ TAO::TAO_SYNCHRONOUS_INVOCATION,
+ true); // is_dii_request
+
+ _tao_call.invoke (0,
+ 0
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+CORBA::Request::send_deferred (ACE_ENV_SINGLE_ARG_DECL)
+{
+ {
+ ACE_GUARD (TAO_SYNCH_MUTEX,
+ ace_mon,
+ this->lock_);
+
+ this->response_received_ = false;
+ }
+ CORBA::Boolean const argument_flag = this->args_->count () ? true : false;
+
+ TAO::NamedValue_Argument _tao_retval (this->result_);
+
+ TAO::NVList_Argument _tao_in_list (this->args_,
+ this->lazy_evaluation_);
+
+ TAO::Argument *_tao_arg_list [] = {
+ &_tao_retval,
+ &_tao_in_list
+ };
+
+ size_t number_args = 0;
+
+ if (argument_flag)
+ number_args = 2;
+ else
+ number_args = 1;
+
+ TAO::DII_Deferred_Invocation_Adapter _tao_call (
+ this->target_,
+ _tao_arg_list,
+ number_args,
+ this->opname_,
+ static_cast<CORBA::ULong> (ACE_OS::strlen (this->opname_)),
+ 0,
+ this->orb_->orb_core (),
+ this);
+
+ _tao_call.invoke (0,
+ 0
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+CORBA::Request::get_response (ACE_ENV_SINGLE_ARG_DECL)
+{
+ while (!this->response_received_)
+ {
+ (void) this->orb_->perform_work (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ if (this->lazy_evaluation_)
+ {
+ this->args_->evaluate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+CORBA::Boolean
+CORBA::Request::poll_response (ACE_ENV_SINGLE_ARG_DECL)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ ace_mon,
+ this->lock_,
+ 0);
+
+ if (!this->response_received_)
+ {
+ // If we're single-threaded, the application could starve the ORB,
+ // and the response never gets received, so let the ORB do an
+ // atom of work, if necessary, each time we poll.
+ ACE_Time_Value tv (0, 0);
+ (void) this->orb_->perform_work (&tv ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+ }
+
+ return this->response_received_;
+}
+
+void
+CORBA::Request::handle_response (TAO_InputCDR &incoming,
+ CORBA::ULong reply_status
+ ACE_ENV_ARG_DECL)
+{
+ // If this request was created by a gateway, then result_
+ // and/or args_ are shared by a CORBA::ServerRequest, whose
+ // reply must be in the same byte order as the reply we are
+ // handling here. So we set the member to be accessed later.
+ this->byte_order_ = incoming.byte_order ();
+
+ switch (reply_status)
+ {
+ case TAO_PLUGGABLE_MESSAGE_NO_EXCEPTION:
+ if (this->result_ != 0)
+ {
+ // We can be sure that the impl is a TAO::Unknown_IDL_Type.
+ this->result_->value ()->impl ()->_tao_decode (incoming
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ this->args_->_tao_incoming_cdr (incoming,
+ CORBA::ARG_OUT | CORBA::ARG_INOUT,
+ this->lazy_evaluation_
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ {
+ ACE_GUARD (TAO_SYNCH_MUTEX,
+ ace_mon,
+ this->lock_);
+
+ this->response_received_ = true;
+ }
+
+ break;
+ case TAO_PLUGGABLE_MESSAGE_USER_EXCEPTION:
+ case TAO_PLUGGABLE_MESSAGE_SYSTEM_EXCEPTION:
+ case TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD:
+ case TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD_PERM:
+ default:
+ // @@ (JP) Don't know what to do about any of these yet.
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) unhandled reply status\n")));
+ }
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL