Request.cpp

Go to the documentation of this file.
00001 // $Id: Request.cpp 80380 2008-01-07 13:11:49Z mcorino $
00002 
00003 #include "tao/DynamicInterface/Request.h"
00004 
00005 ACE_RCSID (DynamicInterface,
00006            Request,
00007            "$Id: Request.cpp 80380 2008-01-07 13:11:49Z mcorino $")
00008 
00009 #include "tao/DynamicInterface/DII_Invocation_Adapter.h"
00010 #include "tao/DynamicInterface/DII_Arguments.h"
00011 #include "tao/DynamicInterface/Context.h"
00012 
00013 #if defined (TAO_HAS_AMI)
00014 #include "tao/Messaging/Asynch_Invocation_Adapter.h"
00015 #include "tao/DynamicInterface/DII_Reply_Handler.h"
00016 #endif /* TAO_HAS_AMI */
00017 
00018 #include "tao/AnyTypeCode/NVList.h"
00019 #include "tao/Object.h"
00020 #include "tao/Pluggable_Messaging_Utils.h"
00021 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
00022 
00023 #include "ace/Log_Msg.h"
00024 #include "ace/OS_NS_string.h"
00025 
00026 #if !defined (__ACE_INLINE__)
00027 # include "tao/DynamicInterface/Request.inl"
00028 #endif /* ! __ACE_INLINE__ */
00029 
00030 
00031 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00032 
00033 // Reference counting for DII Request object.
00034 
00035 CORBA::ULong
00036 CORBA::Request::_incr_refcnt (void)
00037 {
00038   return ++this->refcount_;
00039 }
00040 
00041 CORBA::ULong
00042 CORBA::Request::_decr_refcnt (void)
00043 {
00044   CORBA::ULong const new_count = --this->refcount_;
00045 
00046   if (new_count == 0)
00047     delete this;
00048 
00049   return new_count;
00050 }
00051 
00052 // DII Request class implementation
00053 
00054 CORBA::Request::Request (CORBA::Object_ptr obj,
00055                          CORBA::ORB_ptr orb,
00056                          const CORBA::Char *op,
00057                          CORBA::NVList_ptr args,
00058                          CORBA::NamedValue_ptr result,
00059                          CORBA::Flags flags,
00060                          CORBA::ExceptionList_ptr exceptions)
00061   : target_ (CORBA::Object::_duplicate (obj)),
00062     orb_ (CORBA::ORB::_duplicate (orb)),
00063     opname_ (CORBA::string_dup (op)),
00064     args_ (CORBA::NVList::_duplicate (args)),
00065     result_ (CORBA::NamedValue::_duplicate (result)),
00066     flags_ (flags),
00067     // env_ (env),
00068     exceptions_ (CORBA::ExceptionList::_duplicate (exceptions)),
00069     contexts_ (0),
00070     ctx_ (CORBA::Context::_nil ()),
00071     refcount_ (1),
00072     lazy_evaluation_ (false),
00073     response_received_ (false),
00074     byte_order_ (TAO_ENCAP_BYTE_ORDER)
00075 {
00076   if (this->exceptions_.in () == 0)
00077     {
00078       CORBA::ExceptionList *tmp = 0;
00079       ACE_NEW (tmp,
00080                CORBA::ExceptionList);
00081 
00082       this->exceptions_ = tmp;
00083     }
00084 }
00085 
00086 CORBA::Request::Request (CORBA::Object_ptr obj,
00087                          CORBA::ORB_ptr orb,
00088                          const CORBA::Char *op)
00089   : target_ (CORBA::Object::_duplicate (obj)),
00090     orb_ (CORBA::ORB::_duplicate (orb)),
00091     opname_ (CORBA::string_dup (op)),
00092     flags_ (0),
00093     // env_ (env),
00094     contexts_ (0),
00095     ctx_ (CORBA::Context::_nil ()),
00096     refcount_ (1),
00097     lazy_evaluation_ (false),
00098     response_received_ (false),
00099     byte_order_ (TAO_ENCAP_BYTE_ORDER)
00100 {
00101   CORBA::ExceptionList *tmp = 0;
00102   ACE_NEW (tmp,
00103            CORBA::ExceptionList);
00104 
00105   this->exceptions_ = tmp;
00106 
00107   ACE_NEW (this->args_,
00108            CORBA::NVList);
00109 
00110   ACE_NEW (this->result_,
00111            CORBA::NamedValue);
00112 }
00113 
00114 CORBA::Request::~Request (void)
00115 {
00116   ACE_ASSERT (refcount_ == 0);
00117 
00118   ::CORBA::release (this->target_);
00119   ::CORBA::string_free ((char*) this->opname_);
00120   this->opname_ = 0;
00121   ::CORBA::release (this->args_);
00122   ::CORBA::release (this->result_);
00123 }
00124 
00125 // The public DII interfaces:  normal and oneway calls.
00126 //
00127 // NOTE that using DII, programmers can get the special behaviour of
00128 // discarding the response for normal calls.  This doesn't change the
00129 // semantics of any OMG-IDL interface, it just streamlines control
00130 // flow in some exotic situations.
00131 
00132 void
00133 CORBA::Request::invoke (void)
00134 {
00135   TAO::NamedValue_Argument _tao_retval (this->result_);
00136 
00137   TAO::NVList_Argument _tao_in_list (this->args_,
00138                                      this->lazy_evaluation_);
00139 
00140   TAO::Argument *_tao_arg_list [] = {
00141     &_tao_retval,
00142     &_tao_in_list
00143   };
00144 
00145   TAO::DII_Invocation_Adapter _tao_call (
00146        this->target_,
00147        _tao_arg_list,
00148        sizeof( _tao_arg_list ) / sizeof( TAO::Argument* ),
00149        this->opname_,
00150        static_cast<CORBA::ULong> (ACE_OS::strlen (this->opname_)),
00151        this->exceptions_.in (),
00152        this);
00153 
00154   _tao_call.invoke (0, 0);
00155 
00156   // If we returned without an exception being thrown the response
00157   // (if any) is assumed to be received.
00158   this->response_received_ = true;
00159   
00160   // If this request was created by a gateway, then result_
00161   // and/or args_ are shared by a CORBA::ServerRequest, whose
00162   // reply must be in the same byte order as the reply we are
00163   // handling here. So we set the member to be accessed later.
00164   this->byte_order_ = _tao_retval.byte_order ();
00165 }
00166 
00167 void
00168 CORBA::Request::send_oneway (void)
00169 {
00170   TAO::NamedValue_Argument _tao_retval (this->result_);
00171 
00172   TAO::NVList_Argument _tao_in_list (this->args_,
00173                                      this->lazy_evaluation_);
00174 
00175   TAO::Argument *_tao_arg_list [] = {
00176     &_tao_retval,
00177     &_tao_in_list
00178   };
00179 
00180   TAO::DII_Oneway_Invocation_Adapter _tao_call (
00181       this->target_,
00182       _tao_arg_list,
00183       sizeof( _tao_arg_list ) / sizeof( TAO::Argument* ),
00184       this->opname_,
00185       static_cast<CORBA::ULong> (ACE_OS::strlen (this->opname_)),
00186       TAO::TAO_SYNCHRONOUS_INVOCATION);
00187 
00188   _tao_call.invoke (0, 0);
00189 }
00190 
00191 void
00192 CORBA::Request::send_deferred (void)
00193 {
00194   {
00195     ACE_GUARD (TAO_SYNCH_MUTEX,
00196                ace_mon,
00197                this->lock_);
00198 
00199     this->response_received_ = false;
00200   }
00201   CORBA::Boolean const argument_flag = this->args_->count () ? true : false;
00202 
00203   TAO::NamedValue_Argument _tao_retval (this->result_);
00204 
00205   TAO::NVList_Argument _tao_in_list (this->args_,
00206                                      this->lazy_evaluation_);
00207 
00208   TAO::Argument *_tao_arg_list [] = {
00209     &_tao_retval,
00210     &_tao_in_list
00211   };
00212 
00213   size_t number_args = 0;
00214 
00215   if (argument_flag)
00216     number_args = 2;
00217   else
00218     number_args = 1;
00219 
00220   TAO::DII_Deferred_Invocation_Adapter _tao_call (
00221       this->target_,
00222       _tao_arg_list,
00223       number_args,
00224       this->opname_,
00225       static_cast<CORBA::ULong> (ACE_OS::strlen (this->opname_)),
00226       0,
00227       this->orb_->orb_core (),
00228       this);
00229 
00230   _tao_call.invoke (0, 0);
00231 }
00232 
00233 #if defined (TAO_HAS_AMI)
00234 void
00235 CORBA::Request::sendc (CORBA::Object_ptr handler)
00236 {
00237   TAO::NamedValue_Argument _tao_retval (this->result_);
00238 
00239   TAO::NVList_Argument _tao_in_list (this->args_,
00240                                      this->lazy_evaluation_);
00241 
00242   TAO::Argument *_tao_arg_list [] = {
00243     &_tao_retval,
00244     &_tao_in_list
00245   };
00246 
00247   TAO::Asynch_Invocation_Adapter _tao_call (
00248        this->target_,
00249        _tao_arg_list,
00250        sizeof( _tao_arg_list ) / sizeof( TAO::Argument* ),
00251        const_cast<char *> (this->opname_),
00252        static_cast<CORBA::ULong> (ACE_OS::strlen (this->opname_)),
00253        0); // collocation proxy broker
00254 
00255   _tao_call.invoke (dynamic_cast<Messaging::ReplyHandler_ptr>(handler),
00256                     &CORBA::Request::_tao_reply_stub);
00257 }
00258 
00259 void
00260 CORBA::Request::_tao_reply_stub (TAO_InputCDR &_tao_in,
00261                                  Messaging::ReplyHandler_ptr rh,
00262                                  CORBA::ULong reply_status)
00263 {
00264   // Retrieve Reply Handler object.
00265   TAO_DII_Reply_Handler* reply_handler =
00266     dynamic_cast<TAO_DII_Reply_Handler*> (rh);
00267 
00268   // Exception handling
00269   switch (reply_status)
00270     {
00271     case TAO_AMI_REPLY_OK:
00272     case TAO_AMI_REPLY_NOT_OK:
00273       {
00274         reply_handler->handle_response(_tao_in);
00275         break;
00276       }
00277     case TAO_AMI_REPLY_USER_EXCEPTION:
00278     case TAO_AMI_REPLY_SYSTEM_EXCEPTION:
00279       {
00280         reply_handler->handle_excep (_tao_in, reply_status);
00281         break;
00282       }
00283     case TAO_AMI_REPLY_LOCATION_FORWARD:
00284     case TAO_AMI_REPLY_LOCATION_FORWARD_PERM:
00285       {
00286         reply_handler->handle_location_forward (_tao_in, reply_status);
00287         break;
00288       }
00289     }
00290 }
00291 #endif /* TAO_HAS_AMI */
00292 
00293 void
00294 CORBA::Request::get_response (void)
00295 {
00296   while (!this->response_received_)
00297     {
00298       (void) this->orb_->perform_work ();
00299     }
00300 
00301   if (this->lazy_evaluation_)
00302     {
00303       this->args_->evaluate ();
00304     }
00305 }
00306 
00307 CORBA::Boolean
00308 CORBA::Request::poll_response (void)
00309 {
00310   CORBA::Boolean response_received = false;
00311 
00312   {
00313     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00314                       ace_mon,
00315                       this->lock_,
00316                       false);
00317     response_received = this->response_received_;
00318   }
00319 
00320   if (!response_received)
00321     {
00322       // If we're single-threaded, the application could starve the ORB,
00323       // and the response never gets received, so let the ORB do an
00324       // atom of work, if necessary, each time we poll.
00325       ACE_Time_Value tv (0, 0);
00326       (void) this->orb_->perform_work (&tv);
00327 
00328       {
00329         ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00330                           ace_mon,
00331                           this->lock_,
00332                           false);
00333         response_received = this->response_received_;
00334       }
00335     }
00336 
00337   return response_received;
00338 }
00339 
00340 void
00341 CORBA::Request::handle_response (TAO_InputCDR &incoming,
00342                                  GIOP::ReplyStatusType reply_status)
00343 {
00344   // If this request was created by a gateway, then result_
00345   // and/or args_ are shared by a CORBA::ServerRequest, whose
00346   // reply must be in the same byte order as the reply we are
00347   // handling here. So we set the member to be accessed later.
00348   this->byte_order_ = incoming.byte_order ();
00349 
00350   switch (reply_status)
00351   {
00352     case GIOP::NO_EXCEPTION:
00353       if (this->result_ != 0)
00354         {
00355           // We can be sure that the impl is a TAO::Unknown_IDL_Type.
00356           this->result_->value ()->impl ()->_tao_decode (incoming);
00357         }
00358 
00359       this->args_->_tao_incoming_cdr (incoming,
00360                                       CORBA::ARG_OUT | CORBA::ARG_INOUT,
00361                                       this->lazy_evaluation_);
00362 
00363       {
00364         ACE_GUARD (TAO_SYNCH_MUTEX,
00365                    ace_mon,
00366                    this->lock_);
00367 
00368         this->response_received_ = true;
00369       }
00370 
00371       break;
00372     case GIOP::USER_EXCEPTION:
00373     case GIOP::SYSTEM_EXCEPTION:
00374     case GIOP::LOCATION_FORWARD:
00375     case GIOP::LOCATION_FORWARD_PERM:
00376     default:
00377       // @@ (JP) Don't know what to do about any of these yet.
00378       ACE_ERROR ((LM_ERROR,
00379                   ACE_TEXT ("(%P|%t) unhandled reply status\n")));
00380   }
00381 }
00382 
00383 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:43:23 2010 for TAO_DynamicInterface by  doxygen 1.4.7