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__ */
25 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
27 // Reference counting for DII Request object.
30 CORBA::Request::_incr_refcount ()
32 return ++this->refcount_
;
36 CORBA::Request::_decr_refcount ()
38 CORBA::ULong
const new_count
= --this->refcount_
;
46 // DII Request class implementation
47 CORBA::Request::Request (CORBA::Object_ptr obj
,
49 const CORBA::Char
*op
,
50 CORBA::NVList_ptr args
,
51 CORBA::NamedValue_ptr result
,
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
)),
61 exceptions_ (CORBA::ExceptionList::_duplicate (exceptions
)),
63 ctx_ (CORBA::Context::_nil ()),
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;
73 CORBA::ExceptionList
);
75 this->exceptions_
= tmp
;
79 CORBA::Request::Request (CORBA::Object_ptr obj
,
81 const CORBA::Char
*op
)
82 : target_ (CORBA::Object::_duplicate (obj
)),
83 orb_ (CORBA::ORB::_duplicate (orb
)),
84 opname_ (CORBA::string_dup (op
)),
88 ctx_ (CORBA::Context::_nil ()),
90 lazy_evaluation_ (false),
91 response_received_ (false),
92 byte_order_ (TAO_ENCAP_BYTE_ORDER
)
94 CORBA::ExceptionList
*tmp
= 0;
96 CORBA::ExceptionList
);
98 this->exceptions_
= tmp
;
100 ACE_NEW (this->args_
,
103 ACE_NEW (this->result_
,
107 CORBA::Request::~Request ()
109 ACE_ASSERT (refcount_
== 0);
111 ::CORBA::release (this->target_
);
112 ::CORBA::string_free ((char*) this->opname_
);
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.
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
[] = {
138 TAO::DII_Invocation_Adapter
_tao_call (
141 sizeof( _tao_arg_list
) / sizeof( TAO::Argument
* ),
143 static_cast<CORBA::ULong
> (std::strlen (this->opname_
)),
144 this->exceptions_
.in (),
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 ();
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
[] = {
176 TAO::DII_Oneway_Invocation_Adapter
_tao_call (
179 sizeof( _tao_arg_list
) / sizeof( TAO::Argument
* ),
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);
191 CORBA::Request::send_deferred ()
194 ACE_GUARD (TAO_SYNCH_MUTEX
,
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
[] = {
212 size_t number_args
= 0;
219 TAO::DII_Deferred_Invocation_Adapter
_tao_call (
222 static_cast<int> (number_args
),
224 std::strlen (this->opname_
),
226 this->orb_
->orb_core (),
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)
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
[] = {
249 TAO::Asynch_Invocation_Adapter
_tao_call (
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
);
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
);
282 case TAO_AMI_REPLY_USER_EXCEPTION
:
283 case TAO_AMI_REPLY_SYSTEM_EXCEPTION
:
285 reply_handler
->handle_excep (_tao_in
, reply_status
);
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
);
296 #endif /* TAO_HAS_AMI */
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 ();
313 CORBA::Request::poll_response ()
315 CORBA::Boolean response_received
= false;
318 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX
,
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
,
338 response_received
= this->response_received_
;
342 return response_received
;
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
,
373 this->response_received_
= true;
377 case GIOP::USER_EXCEPTION
:
378 case GIOP::SYSTEM_EXCEPTION
:
379 case GIOP::LOCATION_FORWARD
:
380 case GIOP::LOCATION_FORWARD_PERM
:
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