Wrapper around a TAO_Server_Request that will be cloned at the proper time. More...
#include <CSD_FW_Server_Request_Wrapper.h>
Public Member Functions | |
FW_Server_Request_Wrapper (TAO_ServerRequest &server_request) | |
Constructor. | |
~FW_Server_Request_Wrapper () | |
Destructor. | |
void | clone () |
Perform the clone operation. | |
void | dispatch (PortableServer::Servant servant) |
Dispatch the request to the servant. | |
void | cancel () |
Cancel the request. | |
Private Member Functions | |
TAO_ServerRequest * | clone (TAO_ServerRequest *&from) |
TAO_InputCDR * | clone (TAO_InputCDR *&from) |
Clone an input cdr stream. | |
bool | clone (TAO_Operation_Details const *&from, TAO_Operation_Details const *&to, TAO_InputCDR *&cdr) |
void | clone (TAO_Tagged_Profile &from, TAO_Tagged_Profile &to) |
Clone the TAO_Tagged_Profile object. | |
void | clone (TAO_Service_Context &from, TAO_Service_Context &to) |
Clone the TAO_Service_Context object. | |
TAO_OutputCDR * | create_new_output_cdr () |
Private Attributes | |
bool | is_clone_ |
TAO_ServerRequest * | request_ |
Pointer to the underlying TAO_ServerRequest object. |
Wrapper around a TAO_Server_Request that will be cloned at the proper time.
This CSD Framework class is used to provide an interface to a TAO_ServerRequest object such that it can be used for CSD strategies that need to clone TAO_Server_Requests (ie, so that they may be placed on a queue to be dispatched by another thread).
There are several purposes for this class, with the main thing being that the TAO_ServerRequest object is not used directly by the CSD Strategies since it is, after all, an internal TAO class that was never meant to be exposed. Future changes to TAO's internal design may cause disruption in the TAO_ServerRequest class. These changes would only need to be accounted for here in this FW_Server_Request_Wrapper class' implementation, and all CSD Strategies will work again. It's a maintenance issue.
Definition at line 60 of file CSD_FW_Server_Request_Wrapper.h.
TAO::CSD::FW_Server_Request_Wrapper::FW_Server_Request_Wrapper | ( | TAO_ServerRequest & | server_request | ) |
Constructor.
Definition at line 11 of file CSD_FW_Server_Request_Wrapper.inl.
TAO::CSD::FW_Server_Request_Wrapper::~FW_Server_Request_Wrapper | ( | ) |
Destructor.
Definition at line 20 of file CSD_FW_Server_Request_Wrapper.cpp.
{ // Only delete the request if we cloned it. if (this->is_clone_) { // The TAO_Tagged_Profile type_id_ may have been duplicated. if (this->request_->profile_.type_id_ != 0) CORBA::string_free ( const_cast<char*> (this->request_->profile_.type_id_)); // Since this TAO_ServerRequest object is a clone, it // "owns" the input and output CDR objects held by the // incoming_ and outgoing_ data members, respectfully. // Thus, for the clone case, the TAO_ServerRequest dtor // needs to release (aka, delete) the CDR objects. delete this->request_->incoming_; // Get the start message block that reference to the data allocated // on the heap. if (this->request_->outgoing_ != 0) { char* buffer = this->request_->outgoing_->begin ()->base (); delete [] buffer; delete this->request_->outgoing_; } if (this->request_->operation_details_ != 0) { char* opname = const_cast<char*> (this->request_->operation_details_->opname_); delete [] opname; if (this->request_->operation_details_->num_args_ > 0) { for (CORBA::ULong i = 0; i < this->request_->operation_details_->num_args_; i++) { delete this->request_->operation_details_->args_[i]; } delete [] this->request_->operation_details_->args_; } delete this->request_->operation_details_; } if (this->request_->transport_ != 0) this->request_->transport_->remove_reference (); delete this->request_; } }
void TAO::CSD::FW_Server_Request_Wrapper::cancel | ( | void | ) |
Cancel the request.
Definition at line 35 of file CSD_FW_Server_Request_Wrapper.inl.
{ // We only need to handle remote requests that are expecting a reply. if (!this->request_->collocated() && !this->request_->sync_with_server() && this->request_->response_expected() && !this->request_->deferred_reply()) { CORBA::NO_IMPLEMENT ex; this->request_->tao_send_reply_exception(ex); } }
TAO_ServerRequest * TAO::CSD::FW_Server_Request_Wrapper::clone | ( | TAO_ServerRequest *& | from | ) | [private] |
Create a deep copy of the request_ object. The other clone methods are used to support the TAO_ServerRequest clone.
Definition at line 158 of file CSD_FW_Server_Request_Wrapper.cpp.
{ // TBD-CSD: Ultimately add an argument for an allocator. TAO_ServerRequest* clone_obj = 0; ACE_NEW_RETURN (clone_obj, TAO_ServerRequest (), 0); // TYPE: TAO_GIOP_Message_Base* // ACTION: Assuming that a shallow-copy is ok here. clone_obj->mesg_base_ = request->mesg_base_; // TYPE: const char* // ACTION: Method performs deep-copy of string contents. clone_obj->operation (CORBA::string_dup (request->operation ()), request->operation_length (), 1); // TYPE: CORBA::Object_var // ACTION: Assignment performs reference-counted copy of object ref. clone_obj->forward_location_ = request->forward_location_; // TYPE: bool // ACTION: Primitive data type assignment clone_obj->is_forwarded_ = request->is_forwarded_; // TYPE: TAO_InputCDR* // ACTION: This *must* be "cloned". if (request->incoming_ != 0) { clone_obj->incoming_ = this->clone (request->incoming_); } // TYPE: TAO_OutputCDR* // ACTION: This *must* be "cloned". if (request->outgoing_ != 0) { clone_obj->outgoing_ = this->create_new_output_cdr (); } // TYPE: TAO_Transport* // ACTION: Assuming that a shallow-copy is ok here. clone_obj->transport_ = request->transport_; if (clone_obj->transport_ != 0) clone_obj->transport_->add_reference (); // TYPE: CORBA::Boolean // ACTION: Primitive data type assignment. clone_obj->response_expected_ = request->response_expected_; // TYPE: CORBA::Boolean // ACTION: Primitive data type assignment. clone_obj->deferred_reply_ = request->deferred_reply_; // TYPE: CORBA::Boolean // ACTION: Primitive data type assignment. clone_obj->sync_with_server_ = request->sync_with_server_; // TYPE: CORBA::Boolean // ACTION: Primitive data type assignment. clone_obj->is_dsi_ = request->is_dsi_; // TYPE: CORBA::ULong // ACTION: Primitive data type assignment. clone_obj->reply_status_ = request->reply_status_; // TYPE: TAO_ORB_Core* // ACTION: Assuming that a shallow-copy is ok here. clone_obj->orb_core_ = request->orb_core_; // TYPE: TAO_Service_Context // ACTION: No copy/assignment operator, so adding/using a clone operation. this->clone (request->request_service_context_, clone_obj->request_service_context_); // TYPE: TAO_Service_Context // ACTION: No copy/assignment operator, so adding/using a clone operation. this->clone (request->reply_service_context_, clone_obj->reply_service_context_); // TYPE: CORBA::ULong // ACTION: Primitive data type assignment. clone_obj->request_id_ = request->request_id_; // TYPE: TAO_Tagged_Profile // ACTION: No copy/assignment operator, so adding/using a clone operation. this->clone (request->profile_, clone_obj->profile_); // TYPE: CORBA::OctetSeq_var // ACTION: Assignment performs reference-counted copy of sequence. clone_obj->requesting_principal_ = request->requesting_principal_; // TYPE: ptrdiff_t // ACTION: Primitive data type assignment (unsigned integral type). clone_obj->dsi_nvlist_align_ = request->dsi_nvlist_align_; // TYPE: TAO_Operation_Details const * const // ACTION: Need to clone this. if (request->operation_details_ != 0) { ACE_ASSERT (request->incoming_ == 0); if (this->clone (request->operation_details_, clone_obj->operation_details_, clone_obj->incoming_) == false) { return 0; } } // TYPE: CORBA::Boolean // ACTION: Primitive data type assignment. clone_obj->argument_flag_ = request->argument_flag_; //#if TAO_HAS_INTERCEPTORS == 1 // TYPE: size_t // ACTION: Primitive data type assignment. // Just leave this alone for a clone. // //clone_obj->interceptor_count_ = request->interceptor_count_; // TYPE: TAO::PICurrent_Impl // ACTION: Copy/assignment operator disabled on purpose. // Just leave this alone for a clone. // // clone_obj->rs_pi_current_ // TYPE: CORBA::OctetSeq_var // ACTION: Assignment performs reference-counted copy of sequence. // Assuming that this is ok. // Just leave this alone for a clone. // //clone_obj->result_seq_ = request->result_seq_; //#endif /* TAO_HAS_INTERCEPTORS == 1 */ if (clone_obj->transport_ != 0) { clone_obj->transport_->assign_translators(clone_obj->incoming_, clone_obj->outgoing_); } return clone_obj; }
void TAO::CSD::FW_Server_Request_Wrapper::clone | ( | TAO_Service_Context & | from, | |
TAO_Service_Context & | to | |||
) | [private] |
Clone the TAO_Service_Context object.
Definition at line 455 of file CSD_FW_Server_Request_Wrapper.cpp.
{ to.service_context_ = from.service_context_; }
void TAO::CSD::FW_Server_Request_Wrapper::clone | ( | TAO_Tagged_Profile & | from, | |
TAO_Tagged_Profile & | to | |||
) | [private] |
Clone the TAO_Tagged_Profile object.
Definition at line 440 of file CSD_FW_Server_Request_Wrapper.cpp.
{ to.orb_core_ = from.orb_core_; to.discriminator_ = from.discriminator_; to.object_key_extracted_ = from.object_key_extracted_; to.object_key_ = from.object_key_; to.profile_ = from.profile_; to.profile_index_ = from.profile_index_; to.type_id_ = from.type_id_ == 0 ? 0 : CORBA::string_dup (from.type_id_); }
bool TAO::CSD::FW_Server_Request_Wrapper::clone | ( | TAO_Operation_Details const *& | from, | |
TAO_Operation_Details const *& | to, | |||
TAO_InputCDR *& | cdr | |||
) | [private] |
Create a deep copy of a TAO_Operation_Details object and marshall the arguments into a TAO_InputCDR stream. The cloned TAO_Operation_Details object is created without any arguments. This would help the skeleton code to determine whether the arguments are in the operation_details_ object or should be demarshalled from the incoming_ stream in the request_ object.
Definition at line 311 of file CSD_FW_Server_Request_Wrapper.cpp.
{ TAO_Operation_Details *& from_non_const = const_cast <TAO_Operation_Details *&>(from); char* cloned_op_name = 0; ACE_NEW_RETURN (cloned_op_name, char[from_non_const->opname_len_ + 1], false); ACE_OS::strncpy(cloned_op_name, from_non_const->opname_, from_non_const->opname_len_); cloned_op_name[from_non_const->opname_len_] = '\0'; // See if we can clone arguments. If we can, the user compiled the // idl with the clonable arguments option, great. If not, then // use the marshaling technique to copy the arguments TAO::Argument** cloned_args = 0; CORBA::ULong num_cloned_args = 0; if (from->num_args_ > 0) { TAO::Argument* retval = from->args_[0]->clone(); if (retval != 0) { ACE_NEW_RETURN (cloned_args, TAO::Argument*[from->num_args_], false); cloned_args[0] = retval; for (CORBA::ULong i = 1; i < from->num_args_; i++) { cloned_args[i] = from->args_[i]->clone(); } num_cloned_args = from->num_args_; } else { static const size_t mb_size = 2048; ACE_NEW_RETURN (cdr, TAO_InputCDR (mb_size), false); // To avoid duplicating and copying the data block, allow the // TAO_OutputCDR to share the data block of TAO_InputCDR's message block. ACE_Message_Block* mb = const_cast<ACE_Message_Block*> (cdr->start ()); TAO_OutputCDR outcdr (mb); if (! from_non_const->marshal_args (outcdr)) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%T) TAO::CSD::FW_Server_Request_Wrapper::") ACE_TEXT("clone TAO_Operation_Details failed\n"))); return false; } // The TAO_OutputCDR made a new message block around the data block // held by the message block owned by the TAO_InputCDR. We need to // make sure that the results of marshaling are propagated back to the // message block in the TAO_InputCDR. const ACE_Message_Block* begin = outcdr.begin (); if (begin == outcdr.current ()) { // A chain was not made, so we can just adjust the read and write // pointers mb->rd_ptr (begin->rd_ptr ()); mb->wr_ptr (begin->wr_ptr ()); } else { // A costly, but necessary, copying of data blocks. This shouldn't // happen that often assuming that the size of the message block // allocated during the allocation of TAO_InputCDR is "big enough" // for most operation parameters. cdr->reset (begin, outcdr.byte_order ()); } } } // CSD-TBD: Eventually need to use allocators. // CSD-TBD: Assert that this->ex_data_ and this->ex_count_ are both == 0 TAO_Operation_Details* to_non_const = 0; ACE_NEW_RETURN (to_non_const, TAO_Operation_Details(cloned_op_name, from_non_const->opname_len_, cloned_args, num_cloned_args, 0, 0), false); // DATA MEMBER: const char *opname_; // DATA MEMBER: CORBA::ULong opname_len_; // DATA MEMBER: CORBA::Boolean argument_flag_; // DATA MEMBER: TAO::Argument **args_; // DATA MEMBER: CORBA::ULong num_args_; // DATA MEMBER: TAO::Exception_Data *ex_data_; // DATA MEMBER: CORBA::ULong ex_count_; // // ACTION: None - handled in ctor // // DATA MEMBER: CORBA::ULong request_id_; // DATA MEMBER: CORBA::Octet response_flags_; // DATA MEMBER: TAO_Target_Specification::TAO_Target_Address addressing_mode_; // DATA MEMBER: TAO_Service_Context request_service_info_; // DATA MEMBER: TAO_Service_Context reply_service_info_; // // ACTION: Use assignment op to copy from "this" object to the clone. // to_non_const->request_id_ = from->request_id_; to_non_const->response_flags_ = from->response_flags_; to_non_const->addressing_mode_ = from->addressing_mode_; // DATA MEMBER: TAO_Service_Context request_service_info_; // DATA MEMBER: TAO_Service_Context reply_service_info_; // // ACTION: Use the TAO_Service_Context clone() method. // this->clone (from_non_const->request_service_info_, to_non_const->request_service_info_); this->clone (from_non_const->reply_service_info_, to_non_const->reply_service_info_); to = to_non_const; return true; }
TAO_InputCDR * TAO::CSD::FW_Server_Request_Wrapper::clone | ( | TAO_InputCDR *& | from | ) | [private] |
Clone an input cdr stream.
Definition at line 300 of file CSD_FW_Server_Request_Wrapper.cpp.
{ TAO_InputCDR* clone_ptr = 0; ACE_NEW_RETURN (clone_ptr, TAO_InputCDR(*from), 0); return clone_ptr; }
void TAO::CSD::FW_Server_Request_Wrapper::clone | ( | void | ) |
Perform the clone operation.
Definition at line 20 of file CSD_FW_Server_Request_Wrapper.inl.
TAO_OutputCDR * TAO::CSD::FW_Server_Request_Wrapper::create_new_output_cdr | ( | ) | [private] |
Create a TAO_OutputCDR stream initialized with a heap allocated buffer.
Definition at line 462 of file CSD_FW_Server_Request_Wrapper.cpp.
{ TAO_OutputCDR* cdr = 0; // A buffer that we will use to initialise the CDR stream char* repbuf = 0; ACE_NEW_RETURN (repbuf, char[ACE_CDR::DEFAULT_BUFSIZE], 0); TAO_GIOP_Message_Version giop_version; this->request_->outgoing_->get_version (giop_version); // Initialze an output CDR on the stack // NOTE: Don't jump to a conclusion as to why we are using the // input_cdr and hence the global pool here. These pools will move // to the lanes anyway at some point of time. Further, it would have // been awesome to have this in TSS. But for some reason the cloning // that happens when the ORB gets flow controlled while writing a // reply is messing things up. We crash horribly. Doing this adds a // lock, we need to set things like this -- put stuff in TSS here // and transfer to global memory when we get flow controlled. We // need to work on the message block to get it right! ACE_NEW_RETURN (cdr, TAO_OutputCDR (repbuf, ACE_CDR::DEFAULT_BUFSIZE, TAO_ENCAP_BYTE_ORDER, this->request_->orb_core_->input_cdr_buffer_allocator (), this->request_->orb_core_->input_cdr_dblock_allocator (), this->request_->orb_core_->input_cdr_msgblock_allocator (), this->request_->orb_core_->orb_params ()->cdr_memcpy_tradeoff (), giop_version.major, giop_version.minor), 0); return cdr; }
void TAO::CSD::FW_Server_Request_Wrapper::dispatch | ( | PortableServer::Servant | servant | ) |
Dispatch the request to the servant.
Definition at line 76 of file CSD_FW_Server_Request_Wrapper.cpp.
{ try { servant->_dispatch(*this->request_, 0); } // Only CORBA exceptions are caught here. catch (const ::CORBA::Exception& ex) { if (this->request_->collocated()) { // For collocated requests, we re-throw the exception. throw; } else if (!this->request_->sync_with_server() && this->request_->response_expected() && !this->request_->deferred_reply()) { // The request is a remote request that is expecting a reply. this->request_->tao_send_reply_exception(ex); } else if (TAO_debug_level > 0) { // It is unfortunate that an exception (probably a system // exception) was thrown by the dispatch code (even by the // user) when the client was not expecting a response. // However, in this case, we cannot close the connection // down, since it really isn't the client's fault. ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) exception thrown ") ACE_TEXT ("but client is not waiting a response\n"))); ex._tao_print_exception ("FW_Server_Request_Wrapper::dispatch ()"); } } catch (...) { // @@ TODO some c++ exception or another, but what do we do with // it? // We are supposed to map it into a CORBA::UNKNOWN exception. // BTW, this cannot be detected if using the <env> mapping. If // we have native exceptions but no support for them in the ORB // we should still be able to catch it. If we don't have native // exceptions it couldn't have been raised in the first place! CORBA::UNKNOWN exception (CORBA::SystemException::_tao_minor_code (TAO_UNHANDLED_SERVER_CXX_EXCEPTION, 0), CORBA::COMPLETED_MAYBE); if (this->request_->collocated()) { // For collocated requests, we re-throw the exception. throw; } else if (!this->request_->sync_with_server() && this->request_->response_expected() && !this->request_->deferred_reply()) { // The request is a remote request that is expecting a reply. this->request_->tao_send_reply_exception(exception); } else if (TAO_debug_level > 0) { // It is unfortunate that an exception (probably a system // exception) was thrown by the dispatch code (even by the // user) when the client was not expecting a response. // However, in this case, we cannot close the connection // down, since it really isn't the client's fault. ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) exception thrown ") ACE_TEXT ("but client is not waiting a response\n"))); exception._tao_print_exception ( "FW_Server_Request_Wrapper::dispatch ()"); } } }
bool TAO::CSD::FW_Server_Request_Wrapper::is_clone_ [private] |
A flag that indicates that the TAO_ServerRequest object is already cloned.
Definition at line 111 of file CSD_FW_Server_Request_Wrapper.h.
TAO_ServerRequest* TAO::CSD::FW_Server_Request_Wrapper::request_ [private] |
Pointer to the underlying TAO_ServerRequest object.
Definition at line 114 of file CSD_FW_Server_Request_Wrapper.h.