Request.cpp

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

Generated on Thu Nov 9 13:04:21 2006 for TAO_DynamicInterface by doxygen 1.3.6