Class representing an Asynchronous-Method-Handling (AMH) ResponseHandler (RH) object. More...
#include <AMH_Response_Handler.h>
Public Member Functions | |
TAO_AMH_Response_Handler () | |
Constructor. | |
virtual | ~TAO_AMH_Response_Handler (void) |
Destructor. | |
virtual void | init (TAO_ServerRequest &server_request, TAO_AMH_BUFFER_ALLOCATOR *allocator) |
Mutators for refcount | |
virtual void | _remove_ref (void) |
Decrement the reference count. | |
Protected Member Functions | |
void | _tao_rh_init_reply (void) |
void | _tao_rh_send_reply (void) |
Sends the marshalled reply back to the client. | |
void | _tao_rh_send_exception (const CORBA::Exception &ex) |
Send back an exception to the client. | |
void | _tao_rh_send_location_forward (CORBA::Object_ptr fwd, CORBA::Boolean is_perm) |
Send back a location forward exception to the client. | |
Protected Attributes | |
TAO_OutputCDR | _tao_out |
The outgoing CDR stream. | |
GIOP::ReplyStatusType | reply_status_ |
Reply status (will be NO_EXCEPTION in the majority of the. | |
Private Types | |
enum | RH_Reply_Status { TAO_RS_UNINITIALIZED, TAO_RS_INITIALIZED, TAO_RS_SENDING, TAO_RS_SENT } |
Private Member Functions | |
TAO_AMH_Response_Handler (const TAO_AMH_Response_Handler &) | |
TAO_AMH_Response_Handler & | operator= (const TAO_AMH_Response_Handler &) |
Private Attributes | |
TAO_GIOP_Message_Base * | mesg_base_ |
Pointer to the original message-base. | |
CORBA::ULong | request_id_ |
Copy of the request-id of the original Server-Request. | |
CORBA::Boolean | response_expected_ |
TAO_Transport * | transport_ |
TAO_ORB_Core * | orb_core_ |
TAO_Service_Context | reply_service_context_ |
The reply service context. | |
CORBA::Boolean | argument_flag_ |
RH_Reply_Status | rh_reply_status_ |
TAO_SYNCH_MUTEX | mutex_ |
Mutex to ensure the AMH-RH method call is thread-safe. | |
TAO_AMH_BUFFER_ALLOCATOR * | allocator_ |
Class representing an Asynchronous-Method-Handling (AMH) ResponseHandler (RH) object.
Class encapsulates state required to send a response back to the client independent of the thread that originally created the state on the activation-record. Thus the required state (copied from TAO_Server_Request) is 'stored' on the heap.
One RH is created for every client request and the RH can be used only once i.e., the asynchronous method can be called only once. This class also encapsulates various initialisation and response-sending functionality that is common to all RHs (generated by the IDL compiler). Thus the IDL-compiler has to generate less code which in turn reduces the overall code size for an application.
Definition at line 66 of file AMH_Response_Handler.h.
enum TAO_AMH_Response_Handler::RH_Reply_Status [private] |
Various states the ResponseHandler can be in.
These states represent various states the RH can be in and the states are used not only in implementing the 'once-only semantics of RHs, but in making sure well the call thread-safe as well.
Definition at line 169 of file AMH_Response_Handler.h.
{ TAO_RS_UNINITIALIZED, TAO_RS_INITIALIZED, TAO_RS_SENDING, TAO_RS_SENT };
TAO_AMH_Response_Handler::TAO_AMH_Response_Handler | ( | ) |
Constructor.
Definition at line 20 of file AMH_Response_Handler.cpp.
: reply_status_ (GIOP::NO_EXCEPTION) , mesg_base_ (0) , request_id_ (0) , transport_ (0) , orb_core_ (0) , argument_flag_ (1) , rh_reply_status_ (TAO_RS_UNINITIALIZED) , allocator_ (0) { }
TAO_AMH_Response_Handler::~TAO_AMH_Response_Handler | ( | void | ) | [virtual] |
Destructor.
Releases the transport and in case of an error, sends the appropriate exception back to the client
Definition at line 32 of file AMH_Response_Handler.cpp.
{ this->transport_->remove_reference (); // Since we are destroying the object we put a huge lock around the // whole destruction process (just paranoid). { ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_); if (this->response_expected_ == 0) //oneway ? { return; } // If the ResponseHandler is being destroyed before a reply has // been sent to the client, we send a system exception // CORBA::NO_RESPONSE, with minor code to indicate the problem. if (this->rh_reply_status_ == TAO_RS_SENT) { return; } } // If sending the exception to the client fails, then we just give // up, release the transport and return. try { CORBA::NO_RESPONSE ex (CORBA::SystemException::_tao_minor_code (TAO_AMH_REPLY_LOCATION_CODE, EFAULT), CORBA::COMPLETED_NO); this->_tao_rh_send_exception (ex); } catch (...) { } }
TAO_AMH_Response_Handler::TAO_AMH_Response_Handler | ( | const TAO_AMH_Response_Handler & | ) | [private] |
void TAO_AMH_Response_Handler::_remove_ref | ( | void | ) | [virtual] |
Decrement the reference count.
Reimplemented from CORBA::Object.
Definition at line 297 of file AMH_Response_Handler.cpp.
{ if (this->refcount_.decrement () > 0) return; if (this->allocator_) { TAO::TAO_Buffer_Allocator<TAO_AMH_Response_Handler, TAO_AMH_BUFFER_ALLOCATOR> allocator (this->allocator_); allocator.release (this); } else { delete this; } }
void TAO_AMH_Response_Handler::_tao_rh_init_reply | ( | void | ) | [protected] |
Sets up the various parameters in anticipation of returning a reply to the client. return/OUT/INOUT arguments are marshalled into the Output stream after this method has been called.
Definition at line 89 of file AMH_Response_Handler.cpp.
{ { ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_); if (this->rh_reply_status_ != TAO_RS_UNINITIALIZED) { // Looks like someone is trying to call an AMH method // more than once // // We assume that the servant has already processed the // request and is now trying to send back the reply. Hence we // say that the operation has completed but let the server // anyway that it is not doing something right. throw ::CORBA::BAD_INV_ORDER (CORBA::SystemException::_tao_minor_code (TAO_AMH_REPLY_LOCATION_CODE, EEXIST), CORBA::COMPLETED_YES); } } // Construct our reply generator. TAO_Pluggable_Reply_Params_Base reply_params; reply_params.request_id_ = this->request_id_; reply_params.service_context_notowned (&(this->reply_service_context_.service_info ())); reply_params.argument_flag_ = this->argument_flag_; reply_params.reply_status (this->reply_status_); { ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_); this->mesg_base_->generate_reply_header (this->_tao_out, reply_params); // We are done initialising the reply this->rh_reply_status_ = TAO_RS_INITIALIZED; } }
void TAO_AMH_Response_Handler::_tao_rh_send_exception | ( | const CORBA::Exception & | ex | ) | [protected] |
Send back an exception to the client.
Definition at line 173 of file AMH_Response_Handler.cpp.
{ { ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_); if (this->rh_reply_status_ != TAO_RS_UNINITIALIZED) { throw ::CORBA::BAD_INV_ORDER ( CORBA::SystemException::_tao_minor_code ( TAO_AMH_REPLY_LOCATION_CODE, ENOTSUP), CORBA::COMPLETED_YES); } this->rh_reply_status_ = TAO_RS_SENDING; } TAO_Pluggable_Reply_Params_Base reply_params; reply_params.request_id_ = this->request_id_; reply_params.svc_ctx_.length (0); reply_params.service_context_notowned (&this->reply_service_context_.service_info ()); reply_params.argument_flag_ = true; // @@ It appears as if there should be a more efficient way to do // this: the caller already knows this because it is part of the // ExceptionHolder information. if (CORBA::SystemException::_downcast (&ex)) { reply_params.reply_status (GIOP::SYSTEM_EXCEPTION); } else { reply_params.reply_status (GIOP::USER_EXCEPTION); } if (this->mesg_base_->generate_exception_reply (this->_tao_out, reply_params, ex) == -1) { throw ::CORBA::INTERNAL (); } // Send the Exception if (this->transport_->send_message (this->_tao_out, 0, TAO_REPLY) == -1) { if (TAO_debug_level > 0) ACE_ERROR ((LM_ERROR, ACE_TEXT ("TAO: (%P|%t|%N|%l): ") ACE_TEXT ("TAO_AMH_Response_Handler:") ACE_TEXT (" could not send exception reply\n"))); } { ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_); this->rh_reply_status_ = TAO_RS_SENT; } }
void TAO_AMH_Response_Handler::_tao_rh_send_location_forward | ( | CORBA::Object_ptr | fwd, | |
CORBA::Boolean | is_perm | |||
) | [protected] |
Send back a location forward exception to the client.
Definition at line 231 of file AMH_Response_Handler.cpp.
{ { ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_); if (this->rh_reply_status_ != TAO_RS_UNINITIALIZED) { throw ::CORBA::BAD_INV_ORDER ( CORBA::SystemException::_tao_minor_code ( TAO_AMH_REPLY_LOCATION_CODE, ENOTSUP), CORBA::COMPLETED_YES); } this->rh_reply_status_ = TAO_RS_SENDING; } TAO_Pluggable_Reply_Params_Base reply_params; reply_params.request_id_ = this->request_id_; reply_params.svc_ctx_.length (0); reply_params.service_context_notowned (&this->reply_service_context_.service_info ()); reply_params.argument_flag_ = true; if (is_perm) { reply_params.reply_status (GIOP::LOCATION_FORWARD_PERM); } else { reply_params.reply_status (GIOP::LOCATION_FORWARD); } if (this->mesg_base_->generate_reply_header (this->_tao_out, reply_params) == -1) { throw ::CORBA::INTERNAL (); } if (!(this->_tao_out << fwd)) { if (TAO_debug_level > 0) ACE_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) ERROR: Unable to marshal ") ACE_TEXT ("forward reference.\n"))); return; } // Send the Exception if (this->transport_->send_message (this->_tao_out, 0, TAO_REPLY) == -1) { if (TAO_debug_level > 0) ACE_ERROR ((LM_ERROR, ACE_TEXT ("TAO: (%P|%t|%N|%l): ") ACE_TEXT ("TAO_AMH_Response_Handler: could not send ") ACE_TEXT ("location forward reply\n"))); } { ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_); this->rh_reply_status_ = TAO_RS_SENT; } }
void TAO_AMH_Response_Handler::_tao_rh_send_reply | ( | void | ) | [protected] |
Sends the marshalled reply back to the client.
Definition at line 129 of file AMH_Response_Handler.cpp.
{ { ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_); // If the reply has not been initialised, raise an exception to the // server-app saying it is not doing something right. if (this->rh_reply_status_ != TAO_RS_INITIALIZED) { throw ::CORBA::BAD_INV_ORDER ( CORBA::SystemException::_tao_minor_code ( TAO_AMH_REPLY_LOCATION_CODE, ENOTSUP), CORBA::COMPLETED_YES); } this->rh_reply_status_ = TAO_RS_SENDING; } // Send the message. int result = this->transport_->send_message (this->_tao_out, 0, TAO_REPLY); if (result == -1) { if (TAO_debug_level > 0) { // No exception but some kind of error, yet a response // is required. ACE_ERROR (( LM_ERROR, ACE_TEXT ("TAO: (%P|%t) %p: cannot send NO_EXCEPTION reply\n"), ACE_TEXT ("TAO_AMH_Response_Handler::_tao_rh_send_reply") )); } } { ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_); this->rh_reply_status_ = TAO_RS_SENT; } }
void TAO_AMH_Response_Handler::init | ( | TAO_ServerRequest & | server_request, | |
TAO_AMH_BUFFER_ALLOCATOR * | allocator | |||
) | [virtual] |
Stores necessary information from a TAO_Server_Request onto the heap
Definition at line 71 of file AMH_Response_Handler.cpp.
{ mesg_base_ = server_request.mesg_base_; request_id_ = server_request.request_id_; response_expected_ = server_request.response_expected_; transport_ = server_request.transport (); orb_core_ = server_request.orb_core (); allocator_ = allocator; TAO_GIOP_Message_Version v; server_request.outgoing()->get_version(v); this->_tao_out.set_version(v.major, v.minor); this->transport_->assign_translators (0, &this->_tao_out); this->transport_->add_reference (); }
TAO_AMH_Response_Handler& TAO_AMH_Response_Handler::operator= | ( | const TAO_AMH_Response_Handler & | ) | [private] |
TAO_OutputCDR TAO_AMH_Response_Handler::_tao_out [protected] |
The outgoing CDR stream.
The IDL-generated ResponseHandler implementations used this field to marshal the response. Making it a field instead of a public accessor makes the code in the generated ResponseHandler implementation a lot more readable.
Definition at line 123 of file AMH_Response_Handler.h.
Allocator used to allocate this object. If zero then we are allocated from the heap
Definition at line 190 of file AMH_Response_Handler.h.
Alwyas set to true (we always have something to return to the client
Definition at line 160 of file AMH_Response_Handler.h.
Pointer to the original message-base.
Definition at line 135 of file AMH_Response_Handler.h.
TAO_SYNCH_MUTEX TAO_AMH_Response_Handler::mutex_ [private] |
Mutex to ensure the AMH-RH method call is thread-safe.
Definition at line 186 of file AMH_Response_Handler.h.
TAO_ORB_Core* TAO_AMH_Response_Handler::orb_core_ [private] |
A pointer to the ORB Core for the context where the request was created.
Reimplemented from CORBA::Object.
Reimplemented in TAO_AMH_DSI_Response_Handler.
Definition at line 148 of file AMH_Response_Handler.h.
The reply service context.
Definition at line 151 of file AMH_Response_Handler.h.
GIOP::ReplyStatusType TAO_AMH_Response_Handler::reply_status_ [protected] |
Reply status (will be NO_EXCEPTION in the majority of the.
Definition at line 126 of file AMH_Response_Handler.h.
Copy of the request-id of the original Server-Request.
Definition at line 138 of file AMH_Response_Handler.h.
Definition at line 140 of file AMH_Response_Handler.h.
Definition at line 176 of file AMH_Response_Handler.h.
Handle to transport through which the reply will be sent Copy of transport in original Server_Request
Definition at line 144 of file AMH_Response_Handler.h.