00001
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
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
00029
00030
00031 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00032
00033
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
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
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
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
00126
00127
00128
00129
00130
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
00157
00158 this->response_received_ = true;
00159
00160
00161
00162
00163
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);
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
00265 TAO_DII_Reply_Handler* reply_handler =
00266 dynamic_cast<TAO_DII_Reply_Handler*> (rh);
00267
00268
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
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
00323
00324
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
00345
00346
00347
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
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
00378 ACE_ERROR ((LM_ERROR,
00379 ACE_TEXT ("(%P|%t) unhandled reply status\n")));
00380 }
00381 }
00382
00383 TAO_END_VERSIONED_NAMESPACE_DECL