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 + -
显示快捷键?