00001
00002
00003 #include "tao/TAO_Server_Request.h"
00004 #include "tao/ORB_Core.h"
00005 #include "tao/Timeprobe.h"
00006 #include "tao/debug.h"
00007 #include "tao/Pluggable_Messaging.h"
00008 #include "tao/GIOP_Utils.h"
00009 #include "tao/Stub.h"
00010 #include "tao/operation_details.h"
00011 #include "tao/Transport.h"
00012 #include "tao/CDR.h"
00013 #include "tao/SystemException.h"
00014
00015 #if TAO_HAS_INTERCEPTORS == 1
00016 #include "tao/PortableInterceptorC.h"
00017 #include "tao/ServerRequestInterceptor_Adapter.h"
00018 #endif
00019
00020 #if !defined (__ACE_INLINE__)
00021 # include "tao/TAO_Server_Request.inl"
00022 #endif
00023
00024 ACE_RCSID (tao,
00025 TAO_Server_Request,
00026 "$Id: TAO_Server_Request.cpp 79267 2007-08-08 15:51:45Z mesnier_p $")
00027
00028 #if defined (ACE_ENABLE_TIMEPROBES)
00029
00030 static const char * TAO_Server_Request_Timeprobe_Description[] =
00031 {
00032 "TAO_ServerRequest::TAO_ServerRequest - start",
00033 "TAO_ServerRequest::TAO_ServerRequest - end",
00034 };
00035
00036 enum
00037 {
00038
00039 TAO_SERVER_REQUEST_START = 400,
00040 TAO_SERVER_REQUEST_END
00041 };
00042
00043
00044 ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Server_Request_Timeprobe_Description,
00045 TAO_SERVER_REQUEST_START);
00046
00047 #endif
00048
00049 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00050
00051 TAO_ServerRequest::TAO_ServerRequest (TAO_Pluggable_Messaging *mesg_base,
00052 TAO_InputCDR &input,
00053 TAO_OutputCDR &output,
00054 TAO_Transport *transport,
00055 TAO_ORB_Core *orb_core)
00056 : mesg_base_ (mesg_base),
00057 operation_ (0),
00058 operation_len_ (0),
00059 release_operation_ (false),
00060 incoming_ (&input),
00061 outgoing_ (&output),
00062 response_expected_ (false),
00063 deferred_reply_ (false),
00064 sync_with_server_ (false),
00065 is_dsi_ (false),
00066
00067 exception_type_ (TAO_GIOP_NO_EXCEPTION),
00068 orb_core_ (orb_core),
00069 request_id_ (0),
00070 profile_ (orb_core),
00071 requesting_principal_ (0),
00072 dsi_nvlist_align_ (0),
00073 operation_details_ (0),
00074 argument_flag_ (true)
00075 #if TAO_HAS_INTERCEPTORS == 1
00076 , interceptor_count_ (0)
00077 , rs_pi_current_ (0)
00078 , caught_exception_ (0)
00079 , reply_status_ (-1)
00080 #endif
00081 , transport_(transport)
00082 {
00083 ACE_FUNCTION_TIMEPROBE (TAO_SERVER_REQUEST_START);
00084
00085 }
00086
00087
00088 TAO_ServerRequest::TAO_ServerRequest (TAO_Pluggable_Messaging *mesg_base,
00089 CORBA::ULong request_id,
00090 CORBA::Boolean response_expected,
00091 CORBA::Boolean deferred_reply,
00092 TAO::ObjectKey &object_key,
00093 const char *operation,
00094 TAO_OutputCDR &output,
00095 TAO_Transport *transport,
00096 TAO_ORB_Core *orb_core,
00097 int &parse_error)
00098 : mesg_base_ (mesg_base),
00099 operation_ (CORBA::string_dup (operation)),
00100 operation_len_ (operation == 0 ? 0 : ACE_OS::strlen (operation)),
00101 release_operation_ (true),
00102 incoming_ (0),
00103 outgoing_ (&output),
00104 response_expected_ (response_expected),
00105 deferred_reply_ (deferred_reply),
00106 sync_with_server_ (false),
00107 is_dsi_ (false),
00108 exception_type_ (TAO_GIOP_NO_EXCEPTION),
00109 orb_core_ (orb_core),
00110 request_id_ (request_id),
00111 profile_ (orb_core),
00112 requesting_principal_ (0),
00113 dsi_nvlist_align_ (0),
00114 operation_details_ (0),
00115 argument_flag_ (true)
00116 #if TAO_HAS_INTERCEPTORS == 1
00117 , interceptor_count_ (0)
00118 , rs_pi_current_ (0)
00119 , caught_exception_ (0)
00120 , reply_status_ (-1)
00121 #endif
00122 , transport_(transport)
00123 {
00124 this->profile_.object_key (object_key);
00125 parse_error = 0;
00126 }
00127
00128
00129 TAO_ServerRequest::TAO_ServerRequest (TAO_ORB_Core * orb_core,
00130 TAO_Operation_Details const & details,
00131 CORBA::Object_ptr target)
00132 : mesg_base_ (0),
00133 operation_ (details.opname ()),
00134 operation_len_ (details.opname_len ()),
00135 release_operation_ (false),
00136 incoming_ (0),
00137 outgoing_ (0),
00138 response_expected_ (details.response_flags () == TAO_TWOWAY_RESPONSE_FLAG
00139 || details.response_flags () == static_cast<CORBA::Octet> (Messaging::SYNC_WITH_SERVER)
00140 || details.response_flags () == static_cast<CORBA::Octet> (Messaging::SYNC_WITH_TARGET)),
00141 deferred_reply_ (false),
00142 sync_with_server_ (details.response_flags () == static_cast<CORBA::Octet> (Messaging::SYNC_WITH_SERVER)),
00143 is_dsi_ (false),
00144 exception_type_ (TAO_GIOP_NO_EXCEPTION),
00145 orb_core_ (orb_core),
00146 request_id_ (0),
00147 profile_ (orb_core),
00148 requesting_principal_ (0),
00149 dsi_nvlist_align_ (0),
00150 operation_details_ (&details),
00151 argument_flag_ (false)
00152 #if TAO_HAS_INTERCEPTORS == 1
00153 , interceptor_count_ (0)
00154 , rs_pi_current_ (0)
00155 , caught_exception_ (0)
00156 , reply_status_ (-1)
00157 #endif
00158 , transport_ (0)
00159 {
00160
00161 this->profile_.object_key (
00162 const_cast<TAO::ObjectKey &> (target->_stubobj ()->object_key ()));
00163
00164
00165
00166 IOP::ServiceContextList & dest_request_contexts =
00167 this->request_service_context_.service_info ();
00168
00169 IOP::ServiceContextList & src_request_contexts =
00170 (const_cast <TAO_Operation_Details&> (details)).request_service_info ();
00171
00172 dest_request_contexts.replace (src_request_contexts.maximum (),
00173 src_request_contexts.length (),
00174 src_request_contexts.get_buffer (),
00175 false );
00176
00177
00178
00179
00180 }
00181
00182 TAO_ServerRequest::~TAO_ServerRequest (void)
00183 {
00184 #if TAO_HAS_INTERCEPTORS == 1
00185 if (this->rs_pi_current_)
00186 {
00187 TAO::ServerRequestInterceptor_Adapter *interceptor_adapter =
00188 this->orb_core_->serverrequestinterceptor_adapter ();
00189
00190 if (interceptor_adapter)
00191 {
00192 interceptor_adapter->deallocate_pi_current (
00193 this->rs_pi_current_);
00194 }
00195 }
00196 #endif
00197 if (this->release_operation_)
00198 CORBA::string_free (const_cast<char*> (this->operation_));
00199 }
00200
00201 CORBA::ORB_ptr
00202 TAO_ServerRequest::orb (void)
00203 {
00204 return this->orb_core_->orb ();
00205 }
00206
00207 TAO_Service_Context &
00208 TAO_ServerRequest::reply_service_context (void)
00209 {
00210 if (!operation_details_)
00211 {
00212 return this->reply_service_context_;
00213 }
00214 else
00215 {
00216 return const_cast <TAO_Operation_Details*> (
00217 this->operation_details_)->reply_service_context ();
00218 }
00219 }
00220
00221
00222 void
00223 TAO_ServerRequest::init_reply (void)
00224 {
00225 if (!this->outgoing_)
00226 return;
00227
00228
00229 TAO_Pluggable_Reply_Params_Base reply_params;
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 reply_params.request_id_ = this->request_id_;
00240 reply_params.is_dsi_ = this->is_dsi_;
00241 reply_params.dsi_nvlist_align_ = this->dsi_nvlist_align_;
00242
00243
00244 reply_params.service_context_notowned (&this->reply_service_info ());
00245
00246
00247 reply_params.argument_flag_ = this->argument_flag_;
00248
00249
00250 if (!CORBA::is_nil (this->forward_location_.in ()))
00251 {
00252 CORBA::Boolean const permanent_forward_condition =
00253 this->orb_core_->is_permanent_forward_condition (this->forward_location_.in (),
00254 this->request_service_context ());
00255
00256 reply_params.reply_status_
00257 = permanent_forward_condition
00258 ? TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD_PERM
00259 : TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD;
00260 }
00261
00262 else if (this->exception_type_ == TAO_GIOP_NO_EXCEPTION)
00263 {
00264 reply_params.reply_status_ = TAO_PLUGGABLE_MESSAGE_NO_EXCEPTION;
00265 }
00266 else
00267 {
00268 reply_params.reply_status_ = this->exception_type_;
00269 }
00270
00271
00272 this->outgoing_->message_attributes (this->request_id_,
00273 0,
00274 TAO_Transport::TAO_REPLY,
00275 0);
00276
00277
00278 this->mesg_base_->generate_reply_header (*this->outgoing_, reply_params);
00279
00280
00281 if (reply_params.reply_status_ == TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD ||
00282 reply_params.reply_status_ == TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD_PERM)
00283 {
00284
00285 CORBA::Object_ptr object_ptr = this->forward_location_.in ();
00286
00287 if ((*this->outgoing_ << object_ptr) == 0)
00288 {
00289 ACE_DEBUG ((LM_DEBUG,
00290 ACE_TEXT ("TAO (%P|%t) - ServerRequest::init_reply, ")
00291 ACE_TEXT ("TAO_GIOP_ServerRequest::marshal - ")
00292 ACE_TEXT ("marshal encoding forwarded objref failed\n")));
00293 }
00294 }
00295 this->transport_->assign_translators (0, this->outgoing_);
00296 }
00297
00298 void
00299 TAO_ServerRequest::send_no_exception_reply (void)
00300 {
00301
00302 TAO_Pluggable_Reply_Params_Base reply_params;
00303 reply_params.request_id_ = this->request_id_;
00304 reply_params.is_dsi_ = this->is_dsi_;
00305 reply_params.dsi_nvlist_align_ = this->dsi_nvlist_align_;
00306
00307
00308
00309 reply_params.svc_ctx_.length (0);
00310
00311
00312 reply_params.service_context_notowned (&this->reply_service_info ());
00313
00314 reply_params.reply_status_ = TAO_GIOP_NO_EXCEPTION;
00315
00316
00317 reply_params.argument_flag_ = false;
00318
00319 this->outgoing_->message_attributes (this->request_id_,
00320 0,
00321 TAO_Transport::TAO_REPLY,
00322 0);
00323
00324
00325 this->mesg_base_->generate_reply_header (*this->outgoing_, reply_params);
00326
00327 this->outgoing_->more_fragments (false);
00328
00329
00330 int result = this->transport_->send_message (*this->outgoing_,
00331 0,
00332 TAO_Transport::TAO_REPLY);
00333
00334 if (result == -1)
00335 {
00336 if (TAO_debug_level > 0)
00337 {
00338
00339
00340 ACE_ERROR ((
00341 LM_ERROR,
00342 ACE_TEXT ("TAO (%P|%t) - ServerRequest::send_no_exception_reply, ")
00343 ACE_TEXT ("cannot send NO_EXCEPTION reply\n")
00344 ));
00345 }
00346 }
00347 }
00348
00349 void
00350 TAO_ServerRequest::tao_send_reply (void)
00351 {
00352 if (this->collocated ())
00353 return;
00354
00355 this->outgoing_->more_fragments (false);
00356
00357 int result = this->transport_->send_message (*this->outgoing_,
00358 0,
00359 TAO_Transport::TAO_REPLY);
00360 if (result == -1)
00361 {
00362 if (TAO_debug_level > 0)
00363 {
00364
00365
00366 ACE_ERROR ((LM_ERROR,
00367 ACE_TEXT ("TAO (%P|%t) - ServerRequest::tao_send_reply, ")
00368 ACE_TEXT ("cannot send reply\n")));
00369 }
00370 }
00371 }
00372
00373 void
00374 TAO_ServerRequest::tao_send_reply_exception (const CORBA::Exception &ex)
00375 {
00376 if (this->response_expected_ && !this->collocated ())
00377 {
00378
00379 TAO_Pluggable_Reply_Params_Base reply_params;
00380
00381 reply_params.request_id_ = this->request_id_;
00382 reply_params.svc_ctx_.length (0);
00383
00384
00385 reply_params.service_context_notowned (&this->reply_service_info ());
00386
00387
00388 reply_params.argument_flag_ = true;
00389
00390
00391 reply_params.reply_status_ = TAO_GIOP_USER_EXCEPTION;
00392
00393
00394 if (CORBA::SystemException::_downcast (&ex) != 0)
00395 {
00396 reply_params.reply_status_ = TAO_GIOP_SYSTEM_EXCEPTION;
00397 }
00398
00399
00400 #if defined(ACE_INITIALIZE_MEMORY_BEFORE_USE)
00401
00402
00403
00404
00405 char repbuf[ACE_CDR::DEFAULT_BUFSIZE] = { 0 };
00406 #else
00407 char repbuf[ACE_CDR::DEFAULT_BUFSIZE];
00408 #endif
00409 TAO_GIOP_Message_Version gv;
00410 if (this->outgoing_)
00411 this->outgoing_->get_version (gv);
00412
00413 TAO_OutputCDR output (repbuf,
00414 sizeof repbuf,
00415 TAO_ENCAP_BYTE_ORDER,
00416 this->orb_core_->output_cdr_buffer_allocator (),
00417 this->orb_core_->output_cdr_dblock_allocator (),
00418 this->orb_core_->output_cdr_msgblock_allocator (),
00419 this->orb_core_->orb_params ()->cdr_memcpy_tradeoff (),
00420 this->mesg_base_->fragmentation_strategy (),
00421 gv.major,
00422 gv.minor);
00423
00424 this->transport_->assign_translators (0, &output);
00425
00426 if (this->mesg_base_->generate_exception_reply (*this->outgoing_,
00427 reply_params,
00428 ex) == -1)
00429 {
00430 ACE_ERROR ((LM_ERROR,
00431 ACE_TEXT ("TAO (%P|%t) - ServerRequest::tao_send_reply_exception, ")
00432 ACE_TEXT ("could not make exception reply\n")));
00433
00434 }
00435
00436 this->outgoing_->more_fragments (false);
00437
00438
00439 if (this->transport_->send_message (*this->outgoing_,
00440 0,
00441 TAO_Transport::TAO_REPLY) == -1)
00442 {
00443 ACE_ERROR ((LM_ERROR,
00444 ACE_TEXT ("TAO (%P|%t) - ServerRequest::tao_send_reply_exception, ")
00445 ACE_TEXT ("could not send exception reply\n")));
00446 }
00447 }
00448 else if (TAO_debug_level > 0)
00449 {
00450
00451
00452
00453
00454
00455
00456 ACE_ERROR ((LM_ERROR,
00457 ACE_TEXT ("TAO (%P|%t) - ServerRequest::tao_send_reply_exception, ")
00458 ACE_TEXT ("exception thrown ")
00459 ACE_TEXT ("but client is not waiting a response\n")));
00460 }
00461 }
00462
00463 #if TAO_HAS_INTERCEPTORS == 1
00464 void
00465 TAO_ServerRequest::send_cached_reply (CORBA::OctetSeq &s)
00466 {
00467 #if defined(ACE_HAS_PURIFY)
00468
00469
00470
00471
00472 char repbuf[ACE_CDR::DEFAULT_BUFSIZE] = { 0 };
00473 #else
00474 char repbuf[ACE_CDR::DEFAULT_BUFSIZE];
00475 #endif
00476 TAO_GIOP_Message_Version gv;
00477 if (this->outgoing_)
00478 this->outgoing_->get_version (gv);
00479 TAO_OutputCDR output (repbuf,
00480 sizeof repbuf,
00481 TAO_ENCAP_BYTE_ORDER,
00482 this->orb_core_->output_cdr_buffer_allocator (),
00483 this->orb_core_->output_cdr_dblock_allocator (),
00484 this->orb_core_->output_cdr_msgblock_allocator (),
00485 this->orb_core_->orb_params ()->cdr_memcpy_tradeoff (),
00486 this->mesg_base_->fragmentation_strategy (),
00487 gv.major,
00488 gv.minor);
00489
00490 this->transport_->assign_translators (0, &output);
00491
00492
00493 TAO_Pluggable_Reply_Params_Base reply_params;
00494
00495 reply_params.request_id_ = this->request_id_;
00496
00497 reply_params.svc_ctx_.length (0);
00498
00499
00500 reply_params.service_context_notowned (&this->reply_service_info ());
00501
00502
00503 reply_params.argument_flag_ = true;
00504
00505
00506 reply_params.reply_status_ = TAO_GIOP_NO_EXCEPTION;
00507
00508 this->outgoing_->message_attributes (this->request_id_,
00509 0,
00510 TAO_Transport::TAO_REPLY,
00511 0);
00512
00513
00514 if (this->mesg_base_->generate_reply_header (*this->outgoing_,
00515 reply_params) == -1)
00516 {
00517 ACE_ERROR ((LM_ERROR,
00518 ACE_TEXT ("TAO (%P|%t) - ServerRequest::send_cached_reply, ")
00519 ACE_TEXT ("could not make cached reply\n")));
00520
00521 }
00522
00523
00524 this->outgoing_->write_octet_array (
00525 s.get_buffer (),
00526 s.length ());
00527
00528 if (!this->outgoing_->good_bit ())
00529 ACE_ERROR ((LM_ERROR,
00530 ACE_TEXT ("TAO (%P|%t) - ServerRequest::send_cached_reply, ")
00531 ACE_TEXT ("could not marshal reply\n")));
00532
00533 this->outgoing_->more_fragments (false);
00534
00535
00536 if (this->transport_->send_message (*this->outgoing_,
00537 0,
00538 TAO_Transport::TAO_REPLY) == -1)
00539 {
00540 ACE_ERROR ((LM_ERROR,
00541 ACE_TEXT ("TAO (%P|%t) - ServerRequest::send_cached_reply, ")
00542 ACE_TEXT ("could not send cached reply\n")));
00543 }
00544 }
00545
00546 void
00547 TAO_ServerRequest::caught_exception (CORBA::Exception *exception)
00548 {
00549 if (CORBA::SystemException::_downcast (exception) != 0)
00550 this->reply_status_ = PortableInterceptor::SYSTEM_EXCEPTION;
00551 else if (CORBA::UserException::_downcast (exception) != 0)
00552 this->reply_status_ = PortableInterceptor::USER_EXCEPTION;
00553
00554 this->caught_exception_ = exception;
00555 }
00556
00557 TAO::PICurrent_Impl *
00558 TAO_ServerRequest::rs_pi_current (void)
00559 {
00560 if (!this->rs_pi_current_)
00561 {
00562 TAO::ServerRequestInterceptor_Adapter *interceptor_adapter =
00563 this->orb_core_->serverrequestinterceptor_adapter ();
00564
00565 if (interceptor_adapter)
00566 {
00567 this->rs_pi_current_ = interceptor_adapter->allocate_pi_current ();
00568 }
00569 }
00570
00571 return this->rs_pi_current_;
00572 }
00573
00574 TAO_END_VERSIONED_NAMESPACE_DECL
00575
00576 #endif