Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / TAO / tao / DynamicInterface / Request.cpp
blobb8e55c213b53b4d81160c4e82a8484072a08e3a2
1 #include "tao/DynamicInterface/Request.h"
2 #include "tao/DynamicInterface/DII_Invocation_Adapter.h"
3 #include "tao/DynamicInterface/DII_Arguments.h"
4 #include "tao/DynamicInterface/Context.h"
6 #if defined (TAO_HAS_AMI)
7 #include "tao/Messaging/Asynch_Invocation_Adapter.h"
8 #include "tao/DynamicInterface/DII_Reply_Handler.h"
9 #endif /* TAO_HAS_AMI */
11 #include "tao/AnyTypeCode/NVList.h"
12 #include "tao/Object.h"
13 #include "tao/Pluggable_Messaging_Utils.h"
14 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
16 #include "ace/Log_Msg.h"
17 #include "ace/OS_NS_string.h"
19 #if !defined (__ACE_INLINE__)
20 # include "tao/DynamicInterface/Request.inl"
21 #endif /* ! __ACE_INLINE__ */
23 #include <cstring>
25 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
27 // Reference counting for DII Request object.
29 CORBA::ULong
30 CORBA::Request::_incr_refcount ()
32 return ++this->refcount_;
35 CORBA::ULong
36 CORBA::Request::_decr_refcount ()
38 CORBA::ULong const new_count = --this->refcount_;
40 if (new_count == 0)
41 delete this;
43 return new_count;
46 // DII Request class implementation
47 CORBA::Request::Request (CORBA::Object_ptr obj,
48 CORBA::ORB_ptr orb,
49 const CORBA::Char *op,
50 CORBA::NVList_ptr args,
51 CORBA::NamedValue_ptr result,
52 CORBA::Flags flags,
53 CORBA::ExceptionList_ptr exceptions)
54 : target_ (CORBA::Object::_duplicate (obj)),
55 orb_ (CORBA::ORB::_duplicate (orb)),
56 opname_ (CORBA::string_dup (op)),
57 args_ (CORBA::NVList::_duplicate (args)),
58 result_ (CORBA::NamedValue::_duplicate (result)),
59 flags_ (flags),
60 // env_ (env),
61 exceptions_ (CORBA::ExceptionList::_duplicate (exceptions)),
62 contexts_ (0),
63 ctx_ (CORBA::Context::_nil ()),
64 refcount_ (1),
65 lazy_evaluation_ (false),
66 response_received_ (false),
67 byte_order_ (TAO_ENCAP_BYTE_ORDER)
69 if (this->exceptions_.in () == 0)
71 CORBA::ExceptionList *tmp = 0;
72 ACE_NEW (tmp,
73 CORBA::ExceptionList);
75 this->exceptions_ = tmp;
79 CORBA::Request::Request (CORBA::Object_ptr obj,
80 CORBA::ORB_ptr orb,
81 const CORBA::Char *op)
82 : target_ (CORBA::Object::_duplicate (obj)),
83 orb_ (CORBA::ORB::_duplicate (orb)),
84 opname_ (CORBA::string_dup (op)),
85 flags_ (0),
86 // env_ (env),
87 contexts_ (0),
88 ctx_ (CORBA::Context::_nil ()),
89 refcount_ (1),
90 lazy_evaluation_ (false),
91 response_received_ (false),
92 byte_order_ (TAO_ENCAP_BYTE_ORDER)
94 CORBA::ExceptionList *tmp = 0;
95 ACE_NEW (tmp,
96 CORBA::ExceptionList);
98 this->exceptions_ = tmp;
100 ACE_NEW (this->args_,
101 CORBA::NVList);
103 ACE_NEW (this->result_,
104 CORBA::NamedValue);
107 CORBA::Request::~Request ()
109 ACE_ASSERT (refcount_ == 0);
111 ::CORBA::release (this->target_);
112 ::CORBA::string_free ((char*) this->opname_);
113 this->opname_ = 0;
114 ::CORBA::release (this->args_);
115 ::CORBA::release (this->result_);
118 // The public DII interfaces: normal and oneway calls.
120 // NOTE that using DII, programmers can get the special behaviour of
121 // discarding the response for normal calls. This doesn't change the
122 // semantics of any OMG-IDL interface, it just streamlines control
123 // flow in some exotic situations.
125 void
126 CORBA::Request::invoke ()
128 TAO::NamedValue_Argument _tao_retval (this->result_);
130 TAO::NVList_Argument _tao_in_list (this->args_,
131 this->lazy_evaluation_);
133 TAO::Argument *_tao_arg_list [] = {
134 &_tao_retval,
135 &_tao_in_list
138 TAO::DII_Invocation_Adapter _tao_call (
139 this->target_,
140 _tao_arg_list,
141 sizeof( _tao_arg_list ) / sizeof( TAO::Argument* ),
142 this->opname_,
143 static_cast<CORBA::ULong> (std::strlen (this->opname_)),
144 this->exceptions_.in (),
145 this);
147 // forward requested byte order
148 _tao_call._tao_byte_order (this->_tao_byte_order ());
150 _tao_call.invoke (0, 0);
152 // If we returned without an exception being thrown the response
153 // (if any) is assumed to be received.
154 this->response_received_ = true;
156 // If this request was created by a gateway, then result_
157 // and/or args_ are shared by a CORBA::ServerRequest, whose
158 // reply must be in the same byte order as the reply we are
159 // handling here. So we set the member to be accessed later.
160 this->byte_order_ = _tao_retval.byte_order ();
163 void
164 CORBA::Request::send_oneway ()
166 TAO::NamedValue_Argument _tao_retval (this->result_);
168 TAO::NVList_Argument _tao_in_list (this->args_,
169 this->lazy_evaluation_);
171 TAO::Argument *_tao_arg_list [] = {
172 &_tao_retval,
173 &_tao_in_list
176 TAO::DII_Oneway_Invocation_Adapter _tao_call (
177 this->target_,
178 _tao_arg_list,
179 sizeof( _tao_arg_list ) / sizeof( TAO::Argument* ),
180 this->opname_,
181 static_cast<CORBA::ULong> (std::strlen (this->opname_)),
182 TAO::TAO_SYNCHRONOUS_INVOCATION);
184 // forward requested byte order
185 _tao_call._tao_byte_order (this->_tao_byte_order ());
187 _tao_call.invoke (0, 0);
190 void
191 CORBA::Request::send_deferred ()
194 ACE_GUARD (TAO_SYNCH_MUTEX,
195 ace_mon,
196 this->lock_);
198 this->response_received_ = false;
200 CORBA::Boolean const argument_flag = this->args_->count () ? true : false;
202 TAO::NamedValue_Argument _tao_retval (this->result_);
204 TAO::NVList_Argument _tao_in_list (this->args_,
205 this->lazy_evaluation_);
207 TAO::Argument *_tao_arg_list [] = {
208 &_tao_retval,
209 &_tao_in_list
212 size_t number_args = 0;
214 if (argument_flag)
215 number_args = 2;
216 else
217 number_args = 1;
219 TAO::DII_Deferred_Invocation_Adapter _tao_call (
220 this->target_,
221 _tao_arg_list,
222 static_cast<int> (number_args),
223 this->opname_,
224 std::strlen (this->opname_),
226 this->orb_->orb_core (),
227 this);
229 // forward requested byte order
230 _tao_call._tao_byte_order (this->_tao_byte_order ());
232 _tao_call.invoke (0, 0);
235 #if defined (TAO_HAS_AMI)
236 void
237 CORBA::Request::sendc (CORBA::Object_ptr handler)
239 TAO::NamedValue_Argument _tao_retval (this->result_);
241 TAO::NVList_Argument _tao_in_list (this->args_,
242 this->lazy_evaluation_);
244 TAO::Argument *_tao_arg_list [] = {
245 &_tao_retval,
246 &_tao_in_list
249 TAO::Asynch_Invocation_Adapter _tao_call (
250 this->target_,
251 _tao_arg_list,
252 sizeof( _tao_arg_list ) / sizeof( TAO::Argument* ),
253 const_cast<char *> (this->opname_),
254 static_cast<CORBA::ULong> (std::strlen (this->opname_)),
255 0); // collocation proxy broker
257 // forward requested byte order
258 _tao_call._tao_byte_order (this->_tao_byte_order ());
260 _tao_call.invoke (dynamic_cast<Messaging::ReplyHandler_ptr>(handler),
261 &CORBA::Request::_tao_reply_stub);
264 void
265 CORBA::Request::_tao_reply_stub (TAO_InputCDR &_tao_in,
266 Messaging::ReplyHandler_ptr rh,
267 CORBA::ULong reply_status)
269 // Retrieve Reply Handler object.
270 TAO_DII_Reply_Handler* reply_handler =
271 dynamic_cast<TAO_DII_Reply_Handler*> (rh);
273 // Exception handling
274 switch (reply_status)
276 case TAO_AMI_REPLY_OK:
277 case TAO_AMI_REPLY_NOT_OK:
279 reply_handler->handle_response(_tao_in);
280 break;
282 case TAO_AMI_REPLY_USER_EXCEPTION:
283 case TAO_AMI_REPLY_SYSTEM_EXCEPTION:
285 reply_handler->handle_excep (_tao_in, reply_status);
286 break;
288 case TAO_AMI_REPLY_LOCATION_FORWARD:
289 case TAO_AMI_REPLY_LOCATION_FORWARD_PERM:
291 reply_handler->handle_location_forward (_tao_in, reply_status);
292 break;
296 #endif /* TAO_HAS_AMI */
298 void
299 CORBA::Request::get_response ()
301 while (!this->response_received_)
303 (void) this->orb_->perform_work ();
306 if (this->lazy_evaluation_)
308 this->args_->evaluate ();
312 CORBA::Boolean
313 CORBA::Request::poll_response ()
315 CORBA::Boolean response_received = false;
318 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
319 ace_mon,
320 this->lock_,
321 false);
322 response_received = this->response_received_;
325 if (!response_received)
327 // If we're single-threaded, the application could starve the ORB,
328 // and the response never gets received, so let the ORB do an
329 // atom of work, if necessary, each time we poll.
330 ACE_Time_Value tv (0, 0);
331 (void) this->orb_->perform_work (&tv);
334 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
335 ace_mon,
336 this->lock_,
337 false);
338 response_received = this->response_received_;
342 return response_received;
345 void
346 CORBA::Request::handle_response (TAO_InputCDR &incoming,
347 GIOP::ReplyStatusType reply_status)
349 // If this request was created by a gateway, then result_
350 // and/or args_ are shared by a CORBA::ServerRequest, whose
351 // reply must be in the same byte order as the reply we are
352 // handling here. So we set the member to be accessed later.
353 this->byte_order_ = incoming.byte_order ();
355 switch (reply_status)
357 case GIOP::NO_EXCEPTION:
358 if (this->result_ != 0)
360 // We can be sure that the impl is a TAO::Unknown_IDL_Type.
361 this->result_->value ()->impl ()->_tao_decode (incoming);
364 this->args_->_tao_incoming_cdr (incoming,
365 CORBA::ARG_OUT | CORBA::ARG_INOUT,
366 this->lazy_evaluation_);
369 ACE_GUARD (TAO_SYNCH_MUTEX,
370 ace_mon,
371 this->lock_);
373 this->response_received_ = true;
376 break;
377 case GIOP::USER_EXCEPTION:
378 case GIOP::SYSTEM_EXCEPTION:
379 case GIOP::LOCATION_FORWARD:
380 case GIOP::LOCATION_FORWARD_PERM:
381 default:
382 // @@ (JP) Don't know what to do about any of these yet.
383 TAOLIB_ERROR ((LM_ERROR,
384 ACE_TEXT ("TAO (%P|%t) - Request::handle_response, unhandled reply status %d\n"), reply_status));
388 TAO_END_VERSIONED_NAMESPACE_DECL