operation_ss.cpp
来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 751 行 · 第 1/2 页
CPP
751 行
//
// operation_ss.cpp,v 1.79 2003/12/28 16:18:21 wilson_d Exp
//
// ============================================================================
//
// = LIBRARY
// TAO IDL
//
// = FILENAME
// operation_ss.cpp
//
// = DESCRIPTION
// Visitor generating code for Operation in the server skeleton
//
// = AUTHOR
// Aniruddha Gokhale
//
// ============================================================================
ACE_RCSID (be_visitor_operation,
operation_ss,
"operation_ss.cpp,v 1.79 2003/12/28 16:18:21 wilson_d Exp")
// ************************************************************
// Operation visitor for server skeletons
// ************************************************************
be_visitor_operation_ss::be_visitor_operation_ss (be_visitor_context *ctx)
: be_visitor_operation (ctx)
{
}
be_visitor_operation_ss::~be_visitor_operation_ss (void)
{
}
// Processing to be done after every element in the scope is processed.
int
be_visitor_operation_ss::post_process (be_decl *bd)
{
// All we do here is to insert a comma and a newline.
TAO_OutStream *os = this->ctx_->stream ();
if (!this->last_node (bd))
{
*os << ",\n";
}
return 0;
}
int
be_visitor_operation_ss::visit_operation (be_operation *node)
{
TAO_OutStream *os = this->ctx_->stream ();
be_type *bt = 0;
this->ctx_->node (node);
os->indent ();
// If there is an argument of type "native", return immediately.
if (node->has_native ())
{
return 0;
}
// Retrieve the operation return type.
bt = be_type::narrow_from_decl (node->return_type ());
if (!bt)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_visitor_operation_ss::"
"visit_operation - "
"Bad return type\n"),
-1);
}
// We need the interface node in which this operation was defined. However,
// if this operation node was an attribute node in disguise, we get this
// information from the context
be_interface *intf = this->ctx_->attribute ()
? be_interface::narrow_from_scope (this->ctx_->attribute ()->defined_in ())
: be_interface::narrow_from_scope (node->defined_in ());
if (!intf)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_visitor_operation_ss::"
"visit_operation - "
"bad interface scope\n"),
-1);
}
*os << be_nl << be_nl << "// TAO_IDL - Generated from " << be_nl
<< "// " << __FILE__ << ":" << __LINE__ << be_nl << be_nl;
*os << "void " << intf->full_skel_name () << "::";
// Check if we are an attribute node in disguise.
if (this->ctx_->attribute ())
{
// Now check if we are a "get" or "set" operation.
if (node->nmembers () == 1)
{
*os << "_set_";
}
else
{
*os << "_get_";
}
}
*os << node->local_name ()
<< "_skel (" << be_idt << be_idt_nl
<< "TAO_ServerRequest &_tao_server_request," << be_nl
<< "void *_tao_servant," << be_nl
<< "void *_tao_servant_upcall" << be_nl
<< "ACE_ENV_ARG_DECL" << be_uidt_nl
<< ")" << be_uidt_nl;
// Generate the actual code for the skeleton. However, if any of the
// argument types is "native", we do not generate any skeleton
// last argument - is always CORBA::Environment.
*os << "{" << be_idt_nl;
// Generate all the tables and other pre-skel info.
if (this->gen_pre_skel_info (node) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_visitor_operation_ss::"
"visit_operation - "
"gen_pre_skel_info failed\n"),
-1);
}
// Get the right object implementation.
*os << intf->full_skel_name () << " *_tao_impl =" << be_idt_nl
<< "ACE_static_cast (" << be_idt << be_idt_nl
<< intf->full_skel_name () << " *," << be_nl
<< "_tao_servant" << be_uidt_nl
<< ");" << be_uidt << be_uidt_nl;
// Declare a return type variable.
be_visitor_context ctx = *this->ctx_;
be_visitor_operation_rettype_vardecl_ss ord_visitor (&ctx);
// Do we have any arguments in the operation that needs marshalling?
int flag =
node->count_arguments_with_direction (AST_Argument::dir_INOUT |
AST_Argument::dir_OUT);
// Check if the flag is zero and for the return type.
if (flag == 0 && node->void_return_type () == 1)
{
// There are no return type and argument values that needs to be
// marshalled.
*os << "_tao_server_request.argument_flag (0);" << be_nl;
}
if (bt->accept (&ord_visitor) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_visitor_operation_ss::"
"visit_operation - "
"codegen for return var decl failed\n"),
-1);
}
// Declare variables for arguments.
ctx = *this->ctx_;
ctx.state (TAO_CodeGen::TAO_OPERATION_ARG_DECL_SS);
be_visitor_operation_argument oad_visitor (&ctx);
if (node->accept (&oad_visitor) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_visitor_operation_ss::"
"visit_operation - "
"codegen for return var decl failed\n"),
-1);
}
// Demarshal parameters.
if (this->gen_demarshal_params (node, bt) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_visitor_operation_ss::"
"visit_operation - "
"gen_demarshal_params failed\n"),
-1);
}
// Fish out the interceptors.
*os << be_nl
<< "\n#if (TAO_HAS_INTERCEPTORS == 1)" << be_nl;
// Cast the Servant_Upcall pointer.
*os << "TAO_Object_Adapter::Servant_Upcall *_tao_upcall =" << be_idt_nl
<< "ACE_static_cast (" << be_idt << be_idt_nl
<< "TAO_Object_Adapter::Servant_Upcall *," << be_nl
<< "_tao_servant_upcall" << be_uidt_nl
<< ");" << be_uidt_nl << be_uidt_nl;
*os << "TAO_ServerRequestInterceptor_Adapter _tao_vfr ("
<< be_idt << be_idt_nl
<< "_tao_server_request.orb_core ()->server_request_interceptors (),"
<< be_nl
<< "_tao_server_request.interceptor_count ()" << be_uidt_nl
<< ");" << be_uidt_nl << be_nl;
*os << "TAO_ServerRequestInfo_" << node->flat_name ();
// We need the interface node in which this operation was defined. However,
// if this operation node was an attribute node in disguise, we get this
// information from the context and add a "_get"/"_set" to the flat
// name to get around the problem of overloaded methods which are
// generated for attributes.
if (this->ctx_->attribute ())
{
bt = be_type::narrow_from_decl (node->return_type ());
if (!bt)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_visitor_interceptors_ch::"
"visit_operation - "
"Bad return type\n"),
-1);
}
// Grab the right visitor to generate the return type if its not
// void it means it is not the accessor.
if (!this->void_return_type (bt))
{
*os << "_get";
}
else
{
*os << "_set";
}
}
*os << " _tao_ri (" << be_idt << be_idt_nl
<< "_tao_server_request," << be_nl
<< "_tao_upcall," << be_nl
<< "_tao_impl";
// Generate the formal argument fields which are passed to the
// RequestInfo object.
ctx = *this->ctx_;
ctx.state (TAO_CodeGen::TAO_OPERATION_INTERCEPTORS_INFO_ARGLIST_SS);
be_visitor_operation_interceptors_arglist oiia_visitor (&ctx);
if (node->accept (&oiia_visitor) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_visitor_operation_cs::"
"visit_operation - "
"codegen for arglist failed\n"),
-1);
}
*os << be_uidt_nl << ");" << be_uidt_nl << be_nl;
*os << "ACE_TRY" << be_idt_nl
<< "{" << be_idt_nl;
// Create a new scope. The receive_request() interception point and
// the upcall will occur within this scope.
*os << "{" << be_idt_nl;
// Copy the thread scope current (TSC) to the request scope current
// (RSC) upon leaving this scope, i.e. just after the upcall
// completes. A "guard" is used to make the copy also occur if an
// exception is thrown.
*os << "TAO_PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (),"
<< be_nl
<< " 1 /* Copy TSC to RSC */);"
<< be_nl << be_nl;
// Invoke the receive_request() interception point.
*os << "_tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER);" << be_nl
<< "ACE_TRY_CHECK;" << be_nl;
// Check if a PortableInterceptor::ForwardRequest was raised by
// ServerRequestInterceptor::receive_request().
*os << be_nl
<< "if (!_tao_vfr.location_forwarded ())" << be_idt_nl
<< "{" << be_idt;
*os << "\n#endif /* TAO_HAS_INTERCEPTORS */\n";
// Make the upcall and assign to the return val.
ctx = *this->ctx_;
be_visitor_operation_rettype_assign_ss ora_visitor (&ctx);
if (bt->accept (&ora_visitor) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_visitor_operation_ss::"
"visit_operation - "
"codegen for retval assignment failed\n"),
-1);
}
// Make the upcall.
*os << be_idt_nl
<< "_tao_impl->" << node->local_name () << " (" << be_idt << be_idt;
ctx = *this->ctx_;
ctx.state (TAO_CodeGen::TAO_OPERATION_ARG_UPCALL_SS);
be_visitor_operation_argument oau_visitor (&ctx);
if (node->accept (&oau_visitor) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_visitor_operation_ss::"
"visit_operation - "
"codegen for making upcall failed\n"),
-1);
}
// End the upcall.
*os << be_uidt_nl << ");"
<< be_uidt << be_uidt_nl;
if (!be_global->exception_support ())
{
*os << "TAO_INTERCEPTOR_CHECK;";
}
// Update the result.
bt = be_type::narrow_from_decl (node->return_type ());
if (!bt)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_visitor_interceptors_ch::"
"visit_operation - "
"Bad return type\n"),
-1);
}
// Invoke the send_reply() or send_other() interception point, and
// check for exception.
*os << "\n#if (TAO_HAS_INTERCEPTORS == 1)";
// Close scope for "if (!_tao_vfr.location_forwarded ()"
*os << be_uidt_nl
<< "}" << be_uidt;
// Close the TAO_PICurrent_Guard scope
*os << be_uidt_nl
<< "}" << be_nl << be_nl;
// Set reply status only if no PortableInterceptor::ForwardRequest
// was raised by ServerRequestInterceptor::receive_request(). We
// have to make this check a second time because the scope of the
// first check overlaps with the scope of TAO_PICurrent_Guard.
*os << "if (!_tao_vfr.location_forwarded ())" << be_idt_nl
<< "{" << be_idt_nl;
// Grab the right visitor to generate the return type accessor if
// it's not void since we can't have a private member to be of void
// type.
if (!this->void_return_type (bt))
{
// Here's what we are going to do to have a uniform way of
// getting the return value updated for the Request Info:
// declare a operation_retval type object and assign the
// _tao_retval._retn() to it. We pass this to the result
// updation method (note: it hasn't been destroyed). We then
// put it back into the original _tao_retval object. And
// finally the _retn() is returned from the operation without
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?