00001
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
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
00159
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);
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
00261 TAO_DII_Reply_Handler* reply_handler =
00262 dynamic_cast<TAO_DII_Reply_Handler*> (rh);
00263
00264
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
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
00313
00314
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
00335
00336
00337
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
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
00368 ACE_ERROR ((LM_ERROR,
00369 ACE_TEXT ("(%P|%t) unhandled reply status\n")));
00370 }
00371 }
00372
00373 TAO_END_VERSIONED_NAMESPACE_DECL