Request.cpp

Go to the documentation of this file.
00001 // $Id: Request.cpp 78631 2007-06-28 13:49:10Z johnnyw $
00002 
00003 #include "tao/DynamicInterface/Request.h"
00004 
00005 ACE_RCSID (DynamicInterface,
00006            Request,
00007            "$Id: Request.cpp 78631 2007-06-28 13:49:10Z johnnyw $")
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 this request was created by a gateway, then result_
00157   // and/or args_ are shared by a CORBA::ServerRequest, whose
00158   // reply must be in the same byte order as the reply we are
00159   // handling here. So we set the member to be accessed later.
00160   this->byte_order_ = _tao_retval.byte_order ();
00161 }
00162 
00163 void
00164 CORBA::Request::send_oneway (void)
00165 {
00166   TAO::NamedValue_Argument _tao_retval (this->result_);
00167 
00168   TAO::NVList_Argument _tao_in_list (this->args_,
00169                                      this->lazy_evaluation_);
00170 
00171   TAO::Argument *_tao_arg_list [] = {
00172     &_tao_retval,
00173     &_tao_in_list
00174   };
00175 
00176   TAO::DII_Oneway_Invocation_Adapter _tao_call (
00177       this->target_,
00178       _tao_arg_list,
00179       sizeof( _tao_arg_list ) / sizeof( TAO::Argument* ),
00180       this->opname_,
00181       static_cast<CORBA::ULong> (ACE_OS::strlen (this->opname_)),
00182       TAO::TAO_SYNCHRONOUS_INVOCATION);
00183 
00184   _tao_call.invoke (0, 0);
00185 }
00186 
00187 void
00188 CORBA::Request::send_deferred (void)
00189 {
00190   {
00191     ACE_GUARD (TAO_SYNCH_MUTEX,
00192                ace_mon,
00193                this->lock_);
00194 
00195     this->response_received_ = false;
00196   }
00197   CORBA::Boolean const argument_flag = this->args_->count () ? true : false;
00198 
00199   TAO::NamedValue_Argument _tao_retval (this->result_);
00200 
00201   TAO::NVList_Argument _tao_in_list (this->args_,
00202                                      this->lazy_evaluation_);
00203 
00204   TAO::Argument *_tao_arg_list [] = {
00205     &_tao_retval,
00206     &_tao_in_list
00207   };
00208 
00209   size_t number_args = 0;
00210 
00211   if (argument_flag)
00212     number_args = 2;
00213   else
00214     number_args = 1;
00215 
00216   TAO::DII_Deferred_Invocation_Adapter _tao_call (
00217       this->target_,
00218       _tao_arg_list,
00219       number_args,
00220       this->opname_,
00221       static_cast<CORBA::ULong> (ACE_OS::strlen (this->opname_)),
00222       0,
00223       this->orb_->orb_core (),
00224       this);
00225 
00226   _tao_call.invoke (0, 0);
00227 }
00228 
00229 #if defined (TAO_HAS_AMI)
00230 void
00231 CORBA::Request::sendc (CORBA::Object_ptr handler)
00232 {
00233   TAO::NamedValue_Argument _tao_retval (this->result_);
00234 
00235   TAO::NVList_Argument _tao_in_list (this->args_,
00236                                      this->lazy_evaluation_);
00237 
00238   TAO::Argument *_tao_arg_list [] = {
00239     &_tao_retval,
00240     &_tao_in_list
00241   };
00242 
00243   TAO::Asynch_Invocation_Adapter _tao_call (
00244        this->target_,
00245        _tao_arg_list,
00246        sizeof( _tao_arg_list ) / sizeof( TAO::Argument* ),
00247        const_cast<char *> (this->opname_),
00248        static_cast<CORBA::ULong> (ACE_OS::strlen (this->opname_)),
00249        0); // collocation proxy broker
00250 
00251   _tao_call.invoke (dynamic_cast<Messaging::ReplyHandler_ptr>(handler),
00252                     &CORBA::Request::_tao_reply_stub);
00253 }
00254 
00255 void
00256 CORBA::Request::_tao_reply_stub (TAO_InputCDR &_tao_in,
00257                                  Messaging::ReplyHandler_ptr rh,
00258                                  CORBA::ULong reply_status)
00259 {
00260   // Retrieve Reply Handler object.
00261   TAO_DII_Reply_Handler* reply_handler =
00262     dynamic_cast<TAO_DII_Reply_Handler*> (rh);
00263 
00264   // Exception handling
00265   switch (reply_status)
00266     {
00267     case TAO_AMI_REPLY_OK:
00268     case TAO_AMI_REPLY_NOT_OK:
00269       {
00270         reply_handler->handle_response(_tao_in);
00271         break;
00272       }
00273     case TAO_AMI_REPLY_USER_EXCEPTION:
00274     case TAO_AMI_REPLY_SYSTEM_EXCEPTION:
00275       {
00276         reply_handler->handle_excep (_tao_in, reply_status);
00277         break;
00278       }
00279     }
00280 }
00281 #endif /* TAO_HAS_AMI */
00282 
00283 void
00284 CORBA::Request::get_response (void)
00285 {
00286   while (!this->response_received_)
00287     {
00288       (void) this->orb_->perform_work ();
00289     }
00290 
00291   if (this->lazy_evaluation_)
00292     {
00293       this->args_->evaluate ();
00294     }
00295 }
00296 
00297 CORBA::Boolean
00298 CORBA::Request::poll_response (void)
00299 {
00300   CORBA::Boolean response_received = false;
00301 
00302   {
00303     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00304                       ace_mon,
00305                       this->lock_,
00306                       false);
00307     response_received = this->response_received_;
00308   }
00309 
00310   if (!response_received)
00311     {
00312       // If we're single-threaded, the application could starve the ORB,
00313       // and the response never gets received, so let the ORB do an
00314       // atom of work, if necessary, each time we poll.
00315       ACE_Time_Value tv (0, 0);
00316       (void) this->orb_->perform_work (&tv);
00317 
00318       {
00319         ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00320                           ace_mon,
00321                           this->lock_,
00322                           false);
00323         response_received = this->response_received_;
00324       }
00325     }
00326 
00327   return response_received;
00328 }
00329 
00330 void
00331 CORBA::Request::handle_response (TAO_InputCDR &incoming,
00332                                  CORBA::ULong reply_status)
00333 {
00334   // If this request was created by a gateway, then result_
00335   // and/or args_ are shared by a CORBA::ServerRequest, whose
00336   // reply must be in the same byte order as the reply we are
00337   // handling here. So we set the member to be accessed later.
00338   this->byte_order_ = incoming.byte_order ();
00339 
00340   switch (reply_status)
00341   {
00342     case TAO_PLUGGABLE_MESSAGE_NO_EXCEPTION:
00343       if (this->result_ != 0)
00344         {
00345           // We can be sure that the impl is a TAO::Unknown_IDL_Type.
00346           this->result_->value ()->impl ()->_tao_decode (incoming);
00347         }
00348 
00349       this->args_->_tao_incoming_cdr (incoming,
00350                                       CORBA::ARG_OUT | CORBA::ARG_INOUT,
00351                                       this->lazy_evaluation_);
00352 
00353       {
00354         ACE_GUARD (TAO_SYNCH_MUTEX,
00355                    ace_mon,
00356                    this->lock_);
00357 
00358         this->response_received_ = true;
00359       }
00360 
00361       break;
00362     case TAO_PLUGGABLE_MESSAGE_USER_EXCEPTION:
00363     case TAO_PLUGGABLE_MESSAGE_SYSTEM_EXCEPTION:
00364     case TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD:
00365     case TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD_PERM:
00366     default:
00367       // @@ (JP) Don't know what to do about any of these yet.
00368       ACE_ERROR ((LM_ERROR,
00369                   ACE_TEXT ("(%P|%t) unhandled reply status\n")));
00370   }
00371 }
00372 
00373 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 13:37:31 2008 for TAO_DynamicInterface by doxygen 1.3.6