2 #include "tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h"
4 #include "tao/ORB_Constants.h"
5 #include "tao/ORB_Core.h"
6 #include "tao/Transport.h"
9 #if !defined (__ACE_INLINE__)
10 # include "tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl"
11 #endif /* ! __ACE_INLINE__ */
13 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
15 TAO::CSD::FW_Server_Request_Wrapper::~FW_Server_Request_Wrapper()
17 // Only delete the request if we cloned it.
20 // The TAO_Tagged_Profile type_id_ may have been duplicated.
21 if (this->request_
->profile_
.type_id_
!= 0)
23 const_cast<char*> (this->request_
->profile_
.type_id_
));
25 // Since this TAO_ServerRequest object is a clone, it
26 // "owns" the input and output CDR objects held by the
27 // incoming_ and outgoing_ data members, respectfully.
28 // Thus, for the clone case, the TAO_ServerRequest dtor
29 // needs to release (aka, delete) the CDR objects.
30 delete this->request_
->incoming_
;
32 // Get the start message block that reference to the data allocated
34 if (this->request_
->outgoing_
!= 0)
36 char* buffer
= this->request_
->outgoing_
->begin ()->base ();
38 delete this->request_
->outgoing_
;
40 if (this->request_
->operation_details_
!= 0)
43 const_cast<char*> (this->request_
->operation_details_
->opname_
);
46 if (this->request_
->operation_details_
->num_args_
> 0)
48 for (CORBA::ULong i
= 0;
49 i
< this->request_
->operation_details_
->num_args_
; i
++)
51 delete this->request_
->operation_details_
->args_
[i
];
54 delete [] this->request_
->operation_details_
->args_
;
57 delete this->request_
->operation_details_
;
60 if (this->request_
->transport_
!= 0)
61 this->request_
->transport_
->remove_reference ();
63 delete this->request_
;
68 // Assumes that the servant argument is not a NULL pointer.
70 TAO::CSD::FW_Server_Request_Wrapper::dispatch (
71 PortableServer::Servant servant
,
72 TAO::Portable_Server::Servant_Upcall
*servant_upcall
)
76 servant
->_dispatch(*this->request_
, servant_upcall
);
78 // Only CORBA exceptions are caught here.
79 catch (const ::CORBA::Exception
& ex
)
81 if (this->request_
->collocated())
83 // For collocated requests, we re-throw the exception.
86 else if (!this->request_
->sync_with_server() &&
87 this->request_
->response_expected() &&
88 !this->request_
->deferred_reply())
90 // The request is a remote request that is expecting a reply.
91 this->request_
->tao_send_reply_exception(ex
);
93 else if (TAO_debug_level
> 0)
95 // It is unfortunate that an exception (probably a system
96 // exception) was thrown by the dispatch code (even by the
97 // user) when the client was not expecting a response.
98 // However, in this case, we cannot close the connection
99 // down, since it really isn't the client's fault.
101 TAOLIB_ERROR ((LM_ERROR
,
102 ACE_TEXT ("(%P|%t) exception thrown ")
103 ACE_TEXT ("but client is not waiting a response\n")));
105 ex
._tao_print_exception ("FW_Server_Request_Wrapper::dispatch ()");
110 // @@ TODO some c++ exception or another, but what do we do with
112 // We are supposed to map it into a CORBA::UNKNOWN exception.
113 // BTW, this cannot be detected if using the <env> mapping. If
114 // we have native exceptions but no support for them in the ORB
115 // we should still be able to catch it. If we don't have native
116 // exceptions it couldn't have been raised in the first place!
117 CORBA::UNKNOWN
exception (CORBA::SystemException::_tao_minor_code
118 (TAO_UNHANDLED_SERVER_CXX_EXCEPTION
, 0),
119 CORBA::COMPLETED_MAYBE
);
121 if (this->request_
->collocated())
123 // For collocated requests, we re-throw the exception.
126 else if (!this->request_
->sync_with_server() &&
127 this->request_
->response_expected() &&
128 !this->request_
->deferred_reply())
130 // The request is a remote request that is expecting a reply.
131 this->request_
->tao_send_reply_exception(exception
);
133 else if (TAO_debug_level
> 0)
135 // It is unfortunate that an exception (probably a system
136 // exception) was thrown by the dispatch code (even by the
137 // user) when the client was not expecting a response.
138 // However, in this case, we cannot close the connection
139 // down, since it really isn't the client's fault.
141 TAOLIB_ERROR ((LM_ERROR
,
142 ACE_TEXT ("(%P|%t) exception thrown ")
143 ACE_TEXT ("but client is not waiting a response\n")));
145 exception
._tao_print_exception (
146 "FW_Server_Request_Wrapper::dispatch ()");
154 TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_ServerRequest
*& request
)
156 // TBD-CSD: Ultimately add an argument for an allocator.
157 TAO_ServerRequest
* clone_obj
= 0;
158 ACE_NEW_RETURN (clone_obj
,
159 TAO_ServerRequest (),
162 // TYPE: TAO_GIOP_Message_Base*
163 // ACTION: Assuming that a shallow-copy is ok here.
164 clone_obj
->mesg_base_
= request
->mesg_base_
;
167 // ACTION: Method performs deep-copy of string contents.
168 clone_obj
->operation (CORBA::string_dup (request
->operation ()),
169 request
->operation_length (),
172 // TYPE: CORBA::Object_var
173 // ACTION: Assignment performs reference-counted copy of object ref.
174 clone_obj
->forward_location_
= request
->forward_location_
;
177 // ACTION: Primitive data type assignment
178 clone_obj
->is_forwarded_
= request
->is_forwarded_
;
180 // TYPE: TAO_InputCDR*
181 // ACTION: This *must* be "cloned".
182 if (request
->incoming_
!= 0)
184 clone_obj
->incoming_
= this->clone (request
->incoming_
);
187 // TYPE: TAO_OutputCDR*
188 // ACTION: This *must* be "cloned".
189 if (request
->outgoing_
!= 0)
191 clone_obj
->outgoing_
= this->create_new_output_cdr ();
194 // TYPE: TAO_Transport*
195 // ACTION: Assuming that a shallow-copy is ok here.
196 clone_obj
->transport_
= request
->transport_
;
197 if (clone_obj
->transport_
!= 0)
198 clone_obj
->transport_
->add_reference ();
200 // TYPE: CORBA::Boolean
201 // ACTION: Primitive data type assignment.
202 clone_obj
->response_expected_
= request
->response_expected_
;
204 // TYPE: CORBA::Boolean
205 // ACTION: Primitive data type assignment.
206 clone_obj
->deferred_reply_
= request
->deferred_reply_
;
208 // TYPE: CORBA::Boolean
209 // ACTION: Primitive data type assignment.
210 clone_obj
->sync_with_server_
= request
->sync_with_server_
;
212 // TYPE: CORBA::Boolean
213 // ACTION: Primitive data type assignment.
214 clone_obj
->is_dsi_
= request
->is_dsi_
;
216 // TYPE: CORBA::ULong
217 // ACTION: Primitive data type assignment.
218 clone_obj
->reply_status_
= request
->reply_status_
;
220 // TYPE: TAO_ORB_Core*
221 // ACTION: Assuming that a shallow-copy is ok here.
222 clone_obj
->orb_core_
= request
->orb_core_
;
224 // TYPE: TAO_Service_Context
225 // ACTION: No copy/assignment operator, so adding/using a clone operation.
226 this->clone (request
->request_service_context_
, clone_obj
->request_service_context_
);
228 // TYPE: TAO_Service_Context
229 // ACTION: No copy/assignment operator, so adding/using a clone operation.
230 this->clone (request
->reply_service_context_
, clone_obj
->reply_service_context_
);
232 // TYPE: CORBA::ULong
233 // ACTION: Primitive data type assignment.
234 clone_obj
->request_id_
= request
->request_id_
;
236 // TYPE: TAO_Tagged_Profile
237 // ACTION: No copy/assignment operator, so adding/using a clone operation.
238 this->clone (request
->profile_
, clone_obj
->profile_
);
240 // TYPE: CORBA::OctetSeq_var
241 // ACTION: Assignment performs reference-counted copy of sequence.
242 clone_obj
->requesting_principal_
= request
->requesting_principal_
;
245 // ACTION: Primitive data type assignment (unsigned integral type).
246 clone_obj
->dsi_nvlist_align_
= request
->dsi_nvlist_align_
;
248 // TYPE: TAO_Operation_Details const * const
249 // ACTION: Need to clone this.
250 if (request
->operation_details_
!= 0)
252 ACE_ASSERT (request
->incoming_
== 0);
253 if (this->clone (request
->operation_details_
,
254 clone_obj
->operation_details_
,
255 clone_obj
->incoming_
) == false)
261 // TYPE: CORBA::Boolean
262 // ACTION: Primitive data type assignment.
263 clone_obj
->argument_flag_
= request
->argument_flag_
;
265 #if TAO_HAS_INTERCEPTORS == 1
267 // ACTION: Primitive data type assignment.
268 clone_obj
->interceptor_count_
= request
->interceptor_count_
;
270 // TYPE: TAO::PICurrent_Impl
271 // ACTION: Copy/assignment operator disabled on purpose.
272 // Just leave this alone for a clone.
274 // clone_obj->rs_pi_current_
276 // TYPE: CORBA::OctetSeq_var
277 // ACTION: Assignment performs reference-counted copy of sequence.
278 // Assuming that this is ok.
279 // Just leave this alone for a clone.
281 //clone_obj->result_seq_ = request->result_seq_;
282 #endif /* TAO_HAS_INTERCEPTORS == 1 */
284 if (clone_obj
->transport_
!= 0)
286 clone_obj
->transport_
->assign_translators(clone_obj
->incoming_
,
287 clone_obj
->outgoing_
);
294 TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_InputCDR
*& from
)
296 TAO_InputCDR
* clone_ptr
= 0;
297 ACE_NEW_RETURN (clone_ptr
,
305 TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_Operation_Details
const *& from
,
306 TAO_Operation_Details
const *& to
,
309 TAO_Operation_Details
*& from_non_const
310 = const_cast <TAO_Operation_Details
*&>(from
);
312 char* cloned_op_name
= 0;
313 ACE_NEW_RETURN (cloned_op_name
,
314 char[from_non_const
->opname_len_
+ 1],
316 ACE_OS::strncpy(cloned_op_name
, from_non_const
->opname_
, from_non_const
->opname_len_
);
317 cloned_op_name
[from_non_const
->opname_len_
] = '\0';
319 // See if we can clone arguments. If we can, the user compiled the
320 // idl with the clonable arguments option, great. If not, then
321 // use the marshaling technique to copy the arguments
322 TAO::Argument
** cloned_args
= 0;
323 CORBA::ULong num_cloned_args
= 0;
324 if (from
->num_args_
> 0)
326 TAO::Argument
* retval
= from
->args_
[0]->clone();
329 ACE_NEW_RETURN (cloned_args
,
330 TAO::Argument
*[from
->num_args_
],
332 cloned_args
[0] = retval
;
333 for (CORBA::ULong i
= 1; i
< from
->num_args_
; i
++)
335 cloned_args
[i
] = from
->args_
[i
]->clone();
337 num_cloned_args
= from
->num_args_
;
341 static constexpr size_t mb_size
= 2048;
343 TAO_InputCDR (mb_size
),
346 // To avoid duplicating and copying the data block, allow the
347 // TAO_OutputCDR to share the data block of TAO_InputCDR's message block.
348 ACE_Message_Block
* mb
= const_cast<ACE_Message_Block
*> (cdr
->start ());
349 TAO_OutputCDR
outcdr (mb
);
351 if (! from_non_const
->marshal_args (outcdr
))
353 TAOLIB_ERROR ((LM_ERROR
,
354 ACE_TEXT("(%P|%T) TAO::CSD::FW_Server_Request_Wrapper::")
355 ACE_TEXT("clone TAO_Operation_Details failed\n")));
359 // The TAO_OutputCDR made a new message block around the data block
360 // held by the message block owned by the TAO_InputCDR. We need to
361 // make sure that the results of marshaling are propagated back to the
362 // message block in the TAO_InputCDR.
363 const ACE_Message_Block
* begin
= outcdr
.begin ();
364 if (begin
== outcdr
.current ())
366 // A chain was not made, so we can just adjust the read and write
368 mb
->rd_ptr (begin
->rd_ptr ());
369 mb
->wr_ptr (begin
->wr_ptr ());
373 // A costly, but necessary, copying of data blocks. This shouldn't
374 // happen that often assuming that the size of the message block
375 // allocated during the allocation of TAO_InputCDR is "big enough"
376 // for most operation parameters.
377 cdr
->reset (begin
, outcdr
.byte_order ());
382 // CSD-TBD: Eventually need to use allocators.
384 // CSD-TBD: Assert that this->ex_data_ and this->ex_count_ are both == 0
385 TAO_Operation_Details
* to_non_const
= 0;
386 ACE_NEW_RETURN (to_non_const
,
387 TAO_Operation_Details(cloned_op_name
,
388 from_non_const
->opname_len_
,
396 // DATA MEMBER: const char *opname_;
397 // DATA MEMBER: CORBA::ULong opname_len_;
398 // DATA MEMBER: CORBA::Boolean argument_flag_;
399 // DATA MEMBER: TAO::Argument **args_;
400 // DATA MEMBER: CORBA::ULong num_args_;
401 // DATA MEMBER: TAO::Exception_Data *ex_data_;
402 // DATA MEMBER: CORBA::ULong ex_count_;
404 // ACTION: None - handled in ctor
407 // DATA MEMBER: CORBA::ULong request_id_;
408 // DATA MEMBER: CORBA::Octet response_flags_;
409 // DATA MEMBER: TAO_Target_Specification::TAO_Target_Address addressing_mode_;
410 // DATA MEMBER: TAO_Service_Context request_service_info_;
411 // DATA MEMBER: TAO_Service_Context reply_service_info_;
413 // ACTION: Use assignment op to copy from "this" object to the clone.
415 to_non_const
->request_id_
= from
->request_id_
;
416 to_non_const
->response_flags_
= from
->response_flags_
;
417 to_non_const
->addressing_mode_
= from
->addressing_mode_
;
419 // DATA MEMBER: TAO_Service_Context request_service_info_;
420 // DATA MEMBER: TAO_Service_Context reply_service_info_;
422 // ACTION: Use the TAO_Service_Context clone() method.
424 this->clone (from_non_const
->request_service_info_
, to_non_const
->request_service_info_
);
425 this->clone (from_non_const
->reply_service_info_
, to_non_const
->reply_service_info_
);
434 TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_Tagged_Profile
& from
,
435 TAO_Tagged_Profile
& to
)
437 to
.orb_core_
= from
.orb_core_
;
438 to
.discriminator_
= from
.discriminator_
;
439 to
.object_key_extracted_
= from
.object_key_extracted_
;
440 to
.object_key_
= from
.object_key_
;
441 to
.profile_
= from
.profile_
;
442 to
.profile_index_
= from
.profile_index_
;
443 to
.type_id_
= from
.type_id_
== 0 ? 0 :
444 CORBA::string_dup (from
.type_id_
);
449 TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_Service_Context
& from
,
450 TAO_Service_Context
& to
)
452 to
.service_context_
= from
.service_context_
;
456 TAO::CSD::FW_Server_Request_Wrapper::create_new_output_cdr ()
458 TAO_OutputCDR
* cdr
= 0;
460 // A buffer that we will use to initialise the CDR stream
462 ACE_NEW_RETURN (repbuf
,
463 char[ACE_CDR::DEFAULT_BUFSIZE
],
466 TAO_GIOP_Message_Version giop_version
;
467 this->request_
->outgoing_
->get_version (giop_version
);
469 // Initialze an output CDR on the stack
470 // NOTE: Don't jump to a conclusion as to why we are using the
471 // input_cdr and hence the global pool here. These pools will move
472 // to the lanes anyway at some point of time. Further, it would have
473 // been awesome to have this in TSS. But for some reason the cloning
474 // that happens when the ORB gets flow controlled while writing a
475 // reply is messing things up. We crash horribly. Doing this adds a
476 // lock, we need to set things like this -- put stuff in TSS here
477 // and transfer to global memory when we get flow controlled. We
478 // need to work on the message block to get it right!
480 TAO_OutputCDR (repbuf
,
481 ACE_CDR::DEFAULT_BUFSIZE
,
482 TAO_ENCAP_BYTE_ORDER
,
483 this->request_
->orb_core_
->input_cdr_buffer_allocator (),
484 this->request_
->orb_core_
->input_cdr_dblock_allocator (),
485 this->request_
->orb_core_
->input_cdr_msgblock_allocator (),
486 this->request_
->orb_core_
->orb_params ()->cdr_memcpy_tradeoff (),
494 TAO_END_VERSIONED_NAMESPACE_DECL