amh_response_handler.cpp
来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 225 行
CPP
225 行
// AMH_Response_Handler.cpp,v 1.13 2003/10/28 18:29:29 bala Exp
#include "AMH_Response_Handler.h"
#include "tao/TAO_Server_Request.h"
#include "tao/Transport.h"
#include "tao/CDR.h"
#include "tao/ORB_Core.h"
#include "tao/ORB.h"
#include "tao/Pluggable_Messaging.h"
#include "tao/Pluggable_Messaging_Utils.h"
#include "tao/GIOP_Utils.h"
#include "tao/debug.h"
#include "ace/Copy_Disabled.h"
TAO_AMH_Response_Handler::
TAO_AMH_Response_Handler (TAO_ServerRequest &server_request)
: 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 ())
, argument_flag_ (1)
, exception_type_ (TAO_GIOP_NO_EXCEPTION)
, reply_status_ (TAO_RS_UNINITIALIZED)
{
this->transport_->add_reference ();
}
TAO_AMH_Response_Handler::~TAO_AMH_Response_Handler (void)
{
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->reply_status_ == TAO_RS_SENT)
{
return;
}
// It would be slightly more efficient to *NOT* release the lock
// before calling _tao_rh_send_exception(), but this code is way
// out of the critical path.
}
// Is sending the exception to the client fails, then we just
// give up, release the transport and return.
ACE_DECLARE_NEW_CORBA_ENV;
ACE_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 ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
}
ACE_CATCHALL
{
}
ACE_ENDTRY;
ACE_CHECK;
}
void
TAO_AMH_Response_Handler::_tao_rh_init_reply (ACE_ENV_SINGLE_ARG_DECL)
{
{
ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
if (this->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.
ACE_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_;
if (this->exception_type_ == TAO_GIOP_NO_EXCEPTION)
{
reply_params.reply_status_ = TAO_PLUGGABLE_MESSAGE_NO_EXCEPTION;
}
else
{
reply_params.reply_status_ = this->exception_type_;
}
{
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->reply_status_ = TAO_RS_INITIALIZED;
}
}
void
TAO_AMH_Response_Handler::_tao_rh_send_reply (ACE_ENV_SINGLE_ARG_DECL)
{
{
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->reply_status_ != TAO_RS_INITIALIZED)
{
ACE_THROW (CORBA::BAD_INV_ORDER (
CORBA::SystemException::_tao_minor_code (
TAO_AMH_REPLY_LOCATION_CODE,
ENOTSUP),
CORBA::COMPLETED_YES));
}
this->reply_status_ = TAO_RS_SENDING;
}
// Send the message.
int result = this->transport_->send_message (this->_tao_out,
0,
TAO_Transport::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->reply_status_ = TAO_RS_SENT;
}
}
void
TAO_AMH_Response_Handler::_tao_rh_send_exception (CORBA::Exception &ex
ACE_ENV_ARG_DECL)
{
{
ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
if (this->reply_status_ != TAO_RS_UNINITIALIZED)
{
ACE_THROW (CORBA::BAD_INV_ORDER (
CORBA::SystemException::_tao_minor_code (
TAO_AMH_REPLY_LOCATION_CODE,
ENOTSUP),
CORBA::COMPLETED_YES));
}
this->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_ = 1;
reply_params.reply_status_ = TAO_GIOP_USER_EXCEPTION;
// @@ 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_ = TAO_GIOP_SYSTEM_EXCEPTION;
if (this->mesg_base_->generate_exception_reply (this->_tao_out,
reply_params,
ex) == -1)
{
ACE_THROW (CORBA::INTERNAL ());
}
// Send the Exception
if (this->transport_->send_message (this->_tao_out,
0,
TAO_Transport::TAO_REPLY) == -1)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("TAO: (%P|%t|%N|%l): ")
ACE_TEXT ("TAO_AMH_Response_Handler: could not send exception reply\n")));
}
{
ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
this->reply_status_ = TAO_RS_SENT;
}
}
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?