diff options
30 files changed, 997 insertions, 8 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 1c80fcd6c57..a5f7699d574 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,36 @@ +Mon Oct 28 21:27:19 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com> + + * NEWS: + + * TAO_IDL/ast/ast_operation.cpp: + * TAO_IDL/be/be_visitor_operation/ami_cs.cpp: + * TAO_IDL/be/be_visitor_operation/operation.cpp: + * TAO_IDL/include/ast_operation.h: + + Add explicit detection of IN or INOUT operation arguments. If there + are none, then extend the Invocation Adatpter constructor call to + set the new has_in_args flag to false. For backwards compatibility + that flag is defaulted to true. + + * interop-tests/CdrOutArg: + + Added a new test to demonstrate the fix. There is no explicit + regression test for this problem since every CORBA request invokes + this code. + + * tao/GIOP_Message_Generator_Parser_12.cpp: + * tao/Invocation_Adapter.h: + * tao/Invocation_Adapter.inl: + * tao/Invocation_Adapter.cpp: + * tao/Messaging/Asynch_Invocation_Adapter.h: + * tao/Messaging/Asynch_Invocation_Adapter.cpp: + * tao/operation_details.h: + * tao/operation_details.inl: + + Add a new flag, has_in_args, which is true if any of the operation + aguments send data with the request. The CDR buffer taking the + request is aligned after the header only if there is an IN argument. + Mon Oct 28 16:33:43 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com> * orbsvcs/FT_Naming_Service/FT_Naming_Service.cpp: @@ -4,7 +4,12 @@ USER VISIBLE CHANGES BETWEEN TAO-2.2.2 and TAO-2.2.3 USER VISIBLE CHANGES BETWEEN TAO-2.2.1 and TAO-2.2.2 ==================================================== -. None +. Fix for extra CDR padding bytes following a request header when there are no + IN or INOUT arguments in the request. This happened when a request had at least + one OUT argument, and also had a service context that ended off a CDR alignment + boundary. While this is not a problem for TAO-TAO messaging, some non-TAO + servers will reject such requests with a MARSHAL exception. See bug 4141 for more + information. USER VISIBLE CHANGES BETWEEN TAO-2.2.0 and TAO-2.2.1 ==================================================== diff --git a/TAO/TAO_IDL/ast/ast_operation.cpp b/TAO/TAO_IDL/ast/ast_operation.cpp index 037629214bd..a1196fcfa78 100644 --- a/TAO/TAO_IDL/ast/ast_operation.cpp +++ b/TAO/TAO_IDL/ast/ast_operation.cpp @@ -109,6 +109,7 @@ AST_Operation::AST_Operation (AST_Type *rt, pd_context (0), pd_exceptions (0), argument_count_ (-1), + has_in_arguments_ (false), has_native_ (0) { AST_PredefinedType *pdt = 0; @@ -159,6 +160,15 @@ AST_Operation::argument_count (void) return this->argument_count_; } +// Return the IN/INOUT member flag. +bool +AST_Operation::has_in_arguments (void) +{ + this->compute_argument_attr (); + + return this->has_in_arguments_; +} + int AST_Operation::count_arguments_with_direction (int direction_mask) { @@ -258,6 +268,13 @@ AST_Operation::compute_argument_attr (void) arg = AST_Argument::narrow_from_decl (d); + if (arg->direction() == AST_Argument::dir_IN || + arg->direction() == AST_Argument::dir_INOUT) + { + this->has_in_arguments_ = true; + } + + type = AST_Type::narrow_from_decl (arg->field_type ()); if (type->node_type () == AST_Decl::NT_native) diff --git a/TAO/TAO_IDL/be/be_visitor_operation/ami_cs.cpp b/TAO/TAO_IDL/be/be_visitor_operation/ami_cs.cpp index 0391d3ce521..2895f81d563 100644 --- a/TAO/TAO_IDL/be/be_visitor_operation/ami_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_operation/ami_cs.cpp @@ -210,6 +210,13 @@ be_visitor_operation_ami_cs::visit_operation (be_operation *node) *os << " | TAO::TAO_CO_THRU_POA_STRATEGY"; } + if (!node->has_in_arguments ()) + { + *os << "," << be_nl + << "TAO::TAO_ASYNCHRONOUS_CALLBACK_INVOCATION," << be_nl + << "false"; + } + *os << be_uidt_nl << ");" << be_uidt; diff --git a/TAO/TAO_IDL/be/be_visitor_operation/operation.cpp b/TAO/TAO_IDL/be/be_visitor_operation/operation.cpp index e47803ccefc..7e64f339b65 100644 --- a/TAO/TAO_IDL/be/be_visitor_operation/operation.cpp +++ b/TAO/TAO_IDL/be/be_visitor_operation/operation.cpp @@ -294,8 +294,21 @@ be_visitor_operation::gen_stub_operation_body ( if (node->flags () == AST_Operation::OP_oneway) { + *os << "," << be_nl; + *os << "TAO::TAO_ONEWAY_INVOCATION" << be_nl; + } + + if (!node->has_in_arguments ()) + { + if (node->flags () != AST_Operation::OP_oneway) + { + *os << "," << be_nl; + *os << "TAO::TAO_TWOWAY_INVOCATION" << be_nl; + } + *os << "," << be_nl - << "TAO::TAO_ONEWAY_INVOCATION"; + << "TAO::TAO_SYNCHRONOUS_INVOCATION," << be_nl + << "false"; } *os << be_uidt_nl diff --git a/TAO/TAO_IDL/include/ast_operation.h b/TAO/TAO_IDL/include/ast_operation.h index 75fae11e3de..fd3efc4b572 100644 --- a/TAO/TAO_IDL/include/ast_operation.h +++ b/TAO/TAO_IDL/include/ast_operation.h @@ -111,6 +111,9 @@ public: /// Return the number of arguments virtual int argument_count (void); + /// Return the flag indicating a request sends argument data + virtual bool has_in_arguments (void); + /// Count the number of arguments of a certain type. /** * @param direction_mask limit the direction (IN, OUT or INOUT) of @@ -165,6 +168,9 @@ protected: int argument_count_; // Number of arguments. + bool has_in_arguments_; + // True if any arguments are IN or INOUT + int has_native_; // Is any argument of type native. diff --git a/TAO/interop-tests/CdrOutArg/README b/TAO/interop-tests/CdrOutArg/README new file mode 100644 index 00000000000..06130222890 --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/README @@ -0,0 +1,17 @@ +# $Id$ + +This test validates that TAO does not add unneeded CDR alignment bytes as pad when the +only arguments to an operation are out args. The interceptors are necessary to add some +service conotext data that would otherwise require padding. Prior to the fix, and Orbix +server would throw a MARSHAL exception even though the extra bytes are counted in the +message length. + +To build, use MPC to compile a client in the tao directory, then use Orbix defined tools +to build the server in the orbix directory. + +Tu run, issue the following commands, a successful test will have no exceptions and will +terminate the server upon completion. + + orbix/server -o test.ior + + tao/client -k file://test.ior diff --git a/TAO/interop-tests/CdrOutArg/coa.mwc b/TAO/interop-tests/CdrOutArg/coa.mwc new file mode 100644 index 00000000000..b66da202755 --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/coa.mwc @@ -0,0 +1,4 @@ +// $Id$ +workspace { + tao/CdrOutArg.mpc +} diff --git a/TAO/interop-tests/CdrOutArg/idl/test.idl b/TAO/interop-tests/CdrOutArg/idl/test.idl new file mode 100644 index 00000000000..bc825597432 --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/idl/test.idl @@ -0,0 +1,32 @@ + +//============================================================================= +/** + * @file test.idl + * + * $Id$ + * + * Test to verify the correctness of the fix for bug 4141 + * + * @author Phil Mesnier <mesnier_p@ociweb.com> + */ +//============================================================================= + + +module Interop +{ + + interface CDR_Out_Arg + { + // = TITLE + // A test idl for checking interceptor visually. + // + // = DESCRIPTION + // + + void get_out (out long arg); + // Normal operation. + + oneway void shutdown (); + // shutdown the ORB + }; +}; diff --git a/TAO/interop-tests/CdrOutArg/tao/CdrOutArg.mpc b/TAO/interop-tests/CdrOutArg/tao/CdrOutArg.mpc new file mode 100644 index 00000000000..fe508ffe2bf --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/CdrOutArg.mpc @@ -0,0 +1,44 @@ +// -*- MPC -*- +// $Id$ + +project(*idl): taoidldefaults { + IDL_Files { + ../idl/test.idl + } + + Modify_Custom(IDL) { + output_follows_input = 0 + } + + custom_only = 1 +} + +project(*Server): taoserver, pi_server, interceptors { + after += *idl + Source_Files { + test_i.cpp + Server_ORBInitializer.cpp + server_interceptor.cpp + server.cpp + } + Source_Files { + testC.cpp + testS.cpp + } + IDL_Files { + } +} + +project(*Client): taoclient, pi, interceptors { + after += *idl + Source_Files { + Client_ORBInitializer.cpp + client_interceptor.cpp + client.cpp + } + Source_Files { + testC.cpp + } + IDL_Files { + } +} diff --git a/TAO/interop-tests/CdrOutArg/tao/Client_ORBInitializer.cpp b/TAO/interop-tests/CdrOutArg/tao/Client_ORBInitializer.cpp new file mode 100644 index 00000000000..45170534be6 --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/Client_ORBInitializer.cpp @@ -0,0 +1,40 @@ +// -*- C++ -*- +// +// $Id$ +// + +#include "Client_ORBInitializer.h" +#include "client_interceptor.h" + +Client_ORBInitializer::Client_ORBInitializer (void) +{ +} + +void +Client_ORBInitializer::pre_init ( + PortableInterceptor::ORBInitInfo_ptr) +{ +} + +void +Client_ORBInitializer::post_init ( + PortableInterceptor::ORBInitInfo_ptr info) +{ + + CORBA::String_var orb_id = + info->orb_id (); + + PortableInterceptor::ClientRequestInterceptor_ptr interceptor = + PortableInterceptor::ClientRequestInterceptor::_nil (); + + // Install the Echo client request interceptor + ACE_NEW_THROW_EX (interceptor, + Echo_Client_Request_Interceptor (orb_id.in ()), + CORBA::NO_MEMORY ()); + + PortableInterceptor::ClientRequestInterceptor_var + client_interceptor = interceptor; + + info->add_client_request_interceptor (client_interceptor.in ()); +} + diff --git a/TAO/interop-tests/CdrOutArg/tao/Client_ORBInitializer.h b/TAO/interop-tests/CdrOutArg/tao/Client_ORBInitializer.h new file mode 100644 index 00000000000..c6cc9c9ebb8 --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/Client_ORBInitializer.h @@ -0,0 +1,44 @@ +// -*- C++ -*- +// +// $Id$ +// + +#ifndef TAO_CLIENT_ORB_INITIALIZER_H +#define TAO_CLIENT_ORB_INITIALIZER_H +#include /**/ "ace/pre.h" + +#include "tao/PI/PI.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/LocalObject.h" + +// This is to remove "inherits via dominance" warnings from MSVC. +// MSVC is being a little too paranoid. +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +/// Client ORB initializer. +class Client_ORBInitializer : + public virtual PortableInterceptor::ORBInitializer, + public virtual ::CORBA::LocalObject +{ +public: + /// Constructor + Client_ORBInitializer (void); + + virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr info); + + virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info); +}; + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#include /**/ "ace/post.h" +#endif /* TAO_CLIENT_ORB_INITIALIZER_H */ diff --git a/TAO/interop-tests/CdrOutArg/tao/Server_ORBInitializer.cpp b/TAO/interop-tests/CdrOutArg/tao/Server_ORBInitializer.cpp new file mode 100644 index 00000000000..ad369d2b7ed --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/Server_ORBInitializer.cpp @@ -0,0 +1,36 @@ +// -*- C++ -*- +// +// $Id$ +// + +#include "Server_ORBInitializer.h" +#include "server_interceptor.h" + +Server_ORBInitializer::Server_ORBInitializer (void) +{ +} + +void +Server_ORBInitializer::pre_init ( + PortableInterceptor::ORBInitInfo_ptr) +{ +} + +void +Server_ORBInitializer::post_init ( + PortableInterceptor::ORBInitInfo_ptr info) +{ + PortableInterceptor::ServerRequestInterceptor_ptr interceptor = + PortableInterceptor::ServerRequestInterceptor::_nil (); + + // Install the Echo server request interceptor + ACE_NEW_THROW_EX (interceptor, + Echo_Server_Request_Interceptor, + CORBA::NO_MEMORY ()); + + PortableInterceptor::ServerRequestInterceptor_var + server_interceptor = interceptor; + + info->add_server_request_interceptor (server_interceptor.in ()); +} + diff --git a/TAO/interop-tests/CdrOutArg/tao/Server_ORBInitializer.h b/TAO/interop-tests/CdrOutArg/tao/Server_ORBInitializer.h new file mode 100644 index 00000000000..6bffdffaf04 --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/Server_ORBInitializer.h @@ -0,0 +1,44 @@ +// -*- C++ -*- +// +// $Id$ +// + +#ifndef TAO_SERVER_ORB_INITIALIZER_H +#define TAO_SERVER_ORB_INITIALIZER_H +#include /**/ "ace/pre.h" + +#include "tao/PI/PI.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/LocalObject.h" + +// This is to remove "inherits via dominance" warnings from MSVC. +// MSVC is being a little too paranoid. +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +/// Server ORB initializer. +class Server_ORBInitializer : + public virtual PortableInterceptor::ORBInitializer, + public virtual ::CORBA::LocalObject +{ +public: + /// Constructor + Server_ORBInitializer (void); + + virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr info); + + virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info); +}; + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#include /**/ "ace/post.h" +#endif /* TAO_SERVER_ORB_INITIALIZER_H */ diff --git a/TAO/interop-tests/CdrOutArg/tao/client.cpp b/TAO/interop-tests/CdrOutArg/tao/client.cpp new file mode 100644 index 00000000000..106eb7505fa --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/client.cpp @@ -0,0 +1,91 @@ +// $Id$ + +#include "ace/Get_Opt.h" +#include "testC.h" +#include "Client_ORBInitializer.h" + +#include "tao/ORBInitializer_Registry.h" + +const ACE_TCHAR *ior = ACE_TEXT("file://test.ior"); + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("k:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-k <ior> " + "\n", + argv [0]), + -1); + } + return 0; +} + +int +ACE_TMAIN(int argc, ACE_TCHAR *argv[]) +{ + try + { + PortableInterceptor::ORBInitializer_ptr temp_initializer; + + ACE_NEW_RETURN (temp_initializer, + Client_ORBInitializer, + -1); // No exceptions yet! + PortableInterceptor::ORBInitializer_var initializer = + temp_initializer; + + PortableInterceptor::register_orb_initializer (initializer.in ()); + + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv); + + if (parse_args (argc, argv) != 0) + return 1; + + CORBA::Object_var object = + orb->string_to_object (ior); + + Interop::CDR_Out_Arg_var server = + Interop::CDR_Out_Arg::_narrow (object.in ()); + + if (CORBA::is_nil (server.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Object reference <%s> is nil.\n", + ior), + 1); + } + + CORBA::Long lv; + CORBA::Long_out arg (lv); + + server->get_out (arg); + + ACE_DEBUG ((LM_DEBUG, "first call passed\n")); + + server->get_out (arg); + + ACE_DEBUG ((LM_DEBUG, "second call passed\n")); + + server->shutdown (); + + orb->destroy (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Caught exception in client:"); + return 1; + } + + return 0; +} diff --git a/TAO/interop-tests/CdrOutArg/tao/client_interceptor.cpp b/TAO/interop-tests/CdrOutArg/tao/client_interceptor.cpp new file mode 100644 index 00000000000..d119e7ce4c3 --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/client_interceptor.cpp @@ -0,0 +1,121 @@ +// $Id$ + +#include "client_interceptor.h" +#include "tao/OctetSeqC.h" + +#include "ace/Log_Msg.h" +#include "ace/OS_NS_string.h" + +const IOP::ServiceId service_id = 0xdeadbeef; +const char *request_msg = "12345678"; + +Echo_Client_Request_Interceptor:: +Echo_Client_Request_Interceptor (const char *id) + : myname_ ("Echo_Client_Interceptor"), + orb_id_ (CORBA::string_dup (id)) +{ +} + +Echo_Client_Request_Interceptor::~Echo_Client_Request_Interceptor (void) +{ +} + +char * +Echo_Client_Request_Interceptor::name (void) +{ + return CORBA::string_dup (this->myname_); +} + +void +Echo_Client_Request_Interceptor::destroy (void) +{ +} + +void +Echo_Client_Request_Interceptor::send_poll ( + PortableInterceptor::ClientRequestInfo_ptr) +{ +} + +void +Echo_Client_Request_Interceptor::send_request ( + PortableInterceptor::ClientRequestInfo_ptr ri) +{ + + if (CORBA::is_nil (this->orb_.in ())) + { + int argc = 0; + ACE_TCHAR **argv = 0; + this->orb_ = CORBA::ORB_init (argc, argv, + this->orb_id_.in ()); + } + + CORBA::String_var operation = ri->operation (); + + CORBA::Object_var target = ri->target (); + + CORBA::String_var ior = + this->orb_->object_to_string (target.in ()); + +#if 0 + ACE_DEBUG ((LM_DEBUG, + "%C.send_request " + "from \"%C\" on object: %C\n", + this->myname_, + operation.in (), + ior.in ())); +#endif /*if 0*/ + + + + // Populate target member of the ClientRequestInfo. + + // Make the context to send the context to the target + IOP::ServiceContext sc; + sc.context_id = ::service_id; + + CORBA::ULong string_len = ACE_OS::strlen (request_msg) + 1; + CORBA::Octet *buf = CORBA::OctetSeq::allocbuf (string_len); + ACE_OS::strcpy (reinterpret_cast<char *> (buf), request_msg); + + sc.context_data.replace (string_len, string_len, buf, 1); + + // Add this context to the service context list. + ri->add_request_service_context (sc, 0); + + // Check that the request service context can be retrieved. + IOP::ServiceContext_var sc2 = + ri->get_request_service_context (::service_id); + + const char *buf2 = + reinterpret_cast<const char *> (sc2->context_data.get_buffer ()); + + if (ACE_OS::strcmp (buf2, request_msg) != 0) + { + ACE_ERROR ((LM_ERROR, + "ERROR: Expected request service context to be: %C.\n" + " Got: %C\n", + request_msg, + buf2)); + } + +} + +void +Echo_Client_Request_Interceptor::receive_reply ( + PortableInterceptor::ClientRequestInfo_ptr ) +{ +} + +void +Echo_Client_Request_Interceptor::receive_other ( + PortableInterceptor::ClientRequestInfo_ptr) +{ +} + +void +Echo_Client_Request_Interceptor::receive_exception ( + PortableInterceptor::ClientRequestInfo_ptr ) +{ +} + diff --git a/TAO/interop-tests/CdrOutArg/tao/client_interceptor.h b/TAO/interop-tests/CdrOutArg/tao/client_interceptor.h new file mode 100644 index 00000000000..25510e64609 --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/client_interceptor.h @@ -0,0 +1,63 @@ +// -*- C++ -*- +// +// $Id$ + +#ifndef TAO_CLIENT_INTERCEPTOR_H +#define TAO_CLIENT_INTERCEPTOR_H + +#include "tao/PI/PI.h" +#include "tao/PortableInterceptorC.h" +#include "tao/LocalObject.h" +#include "tao/ORB.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +class Echo_Client_Request_Interceptor + : public virtual PortableInterceptor::ClientRequestInterceptor, + public virtual ::CORBA::LocalObject +{ + // = Client-side echo interceptor. For checking interceptor visually only. +public: + Echo_Client_Request_Interceptor (const char *orb_id); + // ctor. + + virtual ~Echo_Client_Request_Interceptor (); + // dtor. + + virtual char * name (void); + // Canonical name of the interceptor. + + virtual void destroy (void); + + virtual void send_poll (PortableInterceptor::ClientRequestInfo_ptr); + + virtual void send_request (PortableInterceptor::ClientRequestInfo_ptr ri); + + virtual void receive_reply (PortableInterceptor::ClientRequestInfo_ptr ri); + + virtual void receive_other (PortableInterceptor::ClientRequestInfo_ptr); + + virtual void receive_exception (PortableInterceptor::ClientRequestInfo_ptr ri); + +private: + const char *myname_; + + CORBA::String_var orb_id_; + // The ID of the ORB where this interceptor was created, usually + // obtained from the ORBInitInfo + + CORBA::ORB_var orb_; +}; + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#endif /* TAO_CLIENT_INTERCEPTOR_H */ diff --git a/TAO/interop-tests/CdrOutArg/tao/server.cpp b/TAO/interop-tests/CdrOutArg/tao/server.cpp new file mode 100644 index 00000000000..7b9a6ad3c05 --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/server.cpp @@ -0,0 +1,121 @@ +// $Id$ + +#include "ace/Get_Opt.h" +#include "test_i.h" +#include "Server_ORBInitializer.h" + +#include "tao/ORBInitializer_Registry.h" +#include "ace/OS_NS_stdio.h" + +const ACE_TCHAR *ior_output_file = ACE_TEXT("test.ior"); + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_output_file = get_opts.opt_arg (); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-o <iorfile>" + "\n", + argv [0]), + -1); + } + // Indicates successful parsing of the command line + return 0; +} + +int +ACE_TMAIN(int argc, ACE_TCHAR *argv[]) +{ + try + { + PortableInterceptor::ORBInitializer_ptr temp_initializer; + + ACE_NEW_RETURN (temp_initializer, + Server_ORBInitializer, + -1); // No exceptions yet! + PortableInterceptor::ORBInitializer_var initializer = + temp_initializer; + + PortableInterceptor::register_orb_initializer (initializer.in ()); + + // Now we can create the ORB + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv); + + CORBA::Object_var poa_object = + orb->resolve_initial_references ("RootPOA"); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + 1); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in ()); + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (); + + poa_manager->activate (); + + if (parse_args (argc, argv) != 0) + return 1; + + CDR_Out_Arg_i server_impl (orb.in ()); + + PortableServer::ObjectId_var id = + root_poa->activate_object (&server_impl); + + CORBA::Object_var test_obj = + root_poa->id_to_reference (id.in ()); + + Interop::CDR_Out_Arg_var server = + Interop::CDR_Out_Arg::_narrow (test_obj.in ()); + + CORBA::String_var ior = + orb->object_to_string (server.in ()); + + ACE_DEBUG ((LM_DEBUG, + "Interop::CDR_Out_Arg: <%C>\n", + ior.in ())); + + // If the ior_output_file exists, output the ior to it + if (ior_output_file != 0) + { + FILE *output_file= ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing IOR: %s", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + } + + orb->run (); + + ACE_DEBUG ((LM_DEBUG, "event loop finished\n")); + + root_poa->destroy (1, 1); + + orb->destroy (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Caught exception in server:"); + return 1; + } + + return 0; +} diff --git a/TAO/interop-tests/CdrOutArg/tao/server_interceptor.cpp b/TAO/interop-tests/CdrOutArg/tao/server_interceptor.cpp new file mode 100644 index 00000000000..e21b78a994c --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/server_interceptor.cpp @@ -0,0 +1,92 @@ +// $Id$ + +#include "server_interceptor.h" +#include "tao/OctetSeqC.h" + +#include "ace/Log_Msg.h" +#include "ace/OS_NS_string.h" + +const IOP::ServiceId service_id = 0xdeadbeef; +const char *request_msg = "12345678"; + + +Echo_Server_Request_Interceptor::Echo_Server_Request_Interceptor (void) + : myname_ ("Echo_Server_Interceptor") +{ +} + +Echo_Server_Request_Interceptor::~Echo_Server_Request_Interceptor (void) +{ +} + +char * +Echo_Server_Request_Interceptor::name (void) +{ + return CORBA::string_dup (this->myname_); +} + +void +Echo_Server_Request_Interceptor::destroy (void) +{ +} + +void +Echo_Server_Request_Interceptor::receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr ri) +{ + + CORBA::String_var operation = ri->operation (); + + ACE_DEBUG ((LM_DEBUG, + "%C.receive_request_service_contexts from " + "\"%C\"\n", + this->myname_, + operation.in ())); + + IOP::ServiceId id = ::service_id; + IOP::ServiceContext_var sc = + ri->get_request_service_context (id); + + const char *buf = + reinterpret_cast<const char *> (sc->context_data.get_buffer ()); +#if 0 + ACE_DEBUG ((LM_DEBUG, + " Received service context: %C\n", + buf)); +#endif /*if 0*/ + + if (ACE_OS::strcmp (buf, request_msg) != 0) + { + ACE_ERROR ((LM_ERROR, + "ERROR: Echo_Server_Request_Interceptor::receive_request_service_contexts: " + "Expected request service context to be: %C\n", + request_msg)); + } + +} + + +void +Echo_Server_Request_Interceptor::receive_request ( + PortableInterceptor::ServerRequestInfo_ptr) +{ + // Do nothing +} + +void +Echo_Server_Request_Interceptor::send_reply ( + PortableInterceptor::ServerRequestInfo_ptr ) +{ +} + +void +Echo_Server_Request_Interceptor::send_exception ( + PortableInterceptor::ServerRequestInfo_ptr ) +{ +} + +void +Echo_Server_Request_Interceptor::send_other ( + PortableInterceptor::ServerRequestInfo_ptr) +{ +} diff --git a/TAO/interop-tests/CdrOutArg/tao/server_interceptor.h b/TAO/interop-tests/CdrOutArg/tao/server_interceptor.h new file mode 100644 index 00000000000..12d511c2291 --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/server_interceptor.h @@ -0,0 +1,58 @@ +// -*- C++ -*- +// +// $Id$ + +#ifndef TAO_SERVER_INTERCEPTOR_H +#define TAO_SERVER_INTERCEPTOR_H + +#include "tao/PI_Server/PI_Server.h" +#include "tao/PortableInterceptorC.h" +#include "tao/LocalObject.h" +#include "tao/ORB.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +class Echo_Server_Request_Interceptor + : public virtual PortableInterceptor::ServerRequestInterceptor, + public virtual ::CORBA::LocalObject +{ + // = Server-side echo interceptor. For checking interceptor visually only. +public: + Echo_Server_Request_Interceptor (void); + // cotr. + + ~Echo_Server_Request_Interceptor (); + // dotr. + + virtual char * name (void); + // Canonical name of the interceptor. + + virtual void destroy (void); + + virtual void receive_request (PortableInterceptor::ServerRequestInfo_ptr ri); + + virtual void receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr); + + virtual void send_reply (PortableInterceptor::ServerRequestInfo_ptr ri); + + virtual void send_exception (PortableInterceptor::ServerRequestInfo_ptr ri); + + virtual void send_other (PortableInterceptor::ServerRequestInfo_ptr); + +private: + const char *myname_; +}; + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#endif /* TAO_SERVER_INTERCEPTOR_H */ diff --git a/TAO/interop-tests/CdrOutArg/tao/test_i.cpp b/TAO/interop-tests/CdrOutArg/tao/test_i.cpp new file mode 100644 index 00000000000..8d4e9c83763 --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/test_i.cpp @@ -0,0 +1,20 @@ +// $Id$ + +#include "test_i.h" + +CDR_Out_Arg_i::CDR_Out_Arg_i (CORBA::ORB_ptr orb) + : orb_ (CORBA::ORB::_duplicate (orb)) +{ +} + +void +CDR_Out_Arg_i::get_out (CORBA::Long_out arg) +{ + arg = 100; +} + +void +CDR_Out_Arg_i::shutdown (void) +{ + this->orb_->shutdown (0); +} diff --git a/TAO/interop-tests/CdrOutArg/tao/test_i.h b/TAO/interop-tests/CdrOutArg/tao/test_i.h new file mode 100644 index 00000000000..2d1c46e48bd --- /dev/null +++ b/TAO/interop-tests/CdrOutArg/tao/test_i.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file test_i.h + * + * $Id$ + * + * @author Phil Mesnier + */ +//============================================================================= + + +#ifndef CDR_OUT_ARG_TEST_I_H +#define CDR_OUT_ARG_TEST_I_H + +#include "testS.h" + +/** + * @class CDR_Out_Arg_i + * + * Implements the CDR_Out_Arg interface + */ +class CDR_Out_Arg_i : public POA_Interop::CDR_Out_Arg +{ + +public: + + CDR_Out_Arg_i (CORBA::ORB_ptr orb); + + void get_out (CORBA::Long_out arg); + + void shutdown (void); + +private: + + /// The ORB pseudo-reference (for shutdown). + CORBA::ORB_var orb_; + +}; + +#endif /* TAO_INTERCEPTOR_TEST_I_H */ diff --git a/TAO/tao/GIOP_Message_Generator_Parser_12.cpp b/TAO/tao/GIOP_Message_Generator_Parser_12.cpp index 88c604c5e3a..30013e41745 100644 --- a/TAO/tao/GIOP_Message_Generator_Parser_12.cpp +++ b/TAO/tao/GIOP_Message_Generator_Parser_12.cpp @@ -83,7 +83,7 @@ TAO_GIOP_Message_Generator_Parser_12::write_request_header ( return false; // We align the pointer only if the operation has arguments. - if (opdetails.argument_flag () + if (opdetails.in_argument_flag () && msg.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1) { return false; diff --git a/TAO/tao/Invocation_Adapter.cpp b/TAO/tao/Invocation_Adapter.cpp index f72485b9884..5ea580f11b1 100644 --- a/TAO/tao/Invocation_Adapter.cpp +++ b/TAO/tao/Invocation_Adapter.cpp @@ -41,6 +41,7 @@ namespace TAO this->op_len_, this->args_, this->number_args_, + this->has_in_args_, ex_data, ex_count); diff --git a/TAO/tao/Invocation_Adapter.h b/TAO/tao/Invocation_Adapter.h index b1ec5f7db19..ff8364806a5 100644 --- a/TAO/tao/Invocation_Adapter.h +++ b/TAO/tao/Invocation_Adapter.h @@ -110,7 +110,8 @@ namespace TAO size_t op_len, int collocation_opportunity, TAO::Invocation_Type type = TAO_TWOWAY_INVOCATION, - TAO::Invocation_Mode mode = TAO_SYNCHRONOUS_INVOCATION); + TAO::Invocation_Mode mode = TAO_SYNCHRONOUS_INVOCATION, + bool has_in_args = true); virtual ~Invocation_Adapter (void); @@ -262,6 +263,8 @@ namespace TAO */ int const number_args_; + bool has_in_args_; + /// Name of the operation. char const * operation_; diff --git a/TAO/tao/Invocation_Adapter.inl b/TAO/tao/Invocation_Adapter.inl index 7acff3aa75a..afc66efda9e 100644 --- a/TAO/tao/Invocation_Adapter.inl +++ b/TAO/tao/Invocation_Adapter.inl @@ -15,10 +15,12 @@ namespace TAO size_t op_len, int collocation_opportunity, Invocation_Type type, - Invocation_Mode mode) + Invocation_Mode mode, + bool has_in_args) : target_ (target) , args_ (args) , number_args_ (arg_number) + , has_in_args_ (has_in_args) , operation_ (operation) , op_len_ (op_len) , collocation_opportunity_ (collocation_opportunity) diff --git a/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp b/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp index 0de1273408c..5a760c4b7e2 100644 --- a/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp +++ b/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp @@ -28,7 +28,8 @@ namespace TAO const char *operation, size_t op_len, int collocation_opportunity, - Invocation_Mode m) + Invocation_Mode m, + bool has_in_args) : Invocation_Adapter (target, args, arg_number, @@ -36,7 +37,8 @@ namespace TAO op_len, collocation_opportunity, TAO_TWOWAY_INVOCATION, - m) + m, + has_in_args) , safe_rd_ () { } diff --git a/TAO/tao/Messaging/Asynch_Invocation_Adapter.h b/TAO/tao/Messaging/Asynch_Invocation_Adapter.h index c562f2fcba8..fe3b1545ffe 100644 --- a/TAO/tao/Messaging/Asynch_Invocation_Adapter.h +++ b/TAO/tao/Messaging/Asynch_Invocation_Adapter.h @@ -68,7 +68,8 @@ namespace TAO const char *operation, size_t op_len, int collocation_opportunity, - TAO::Invocation_Mode mode = TAO_ASYNCHRONOUS_CALLBACK_INVOCATION); + TAO::Invocation_Mode mode = TAO_ASYNCHRONOUS_CALLBACK_INVOCATION, + bool has_in_args = true); void invoke (Messaging::ReplyHandler_ptr reply_handler_ptr, const TAO_Reply_Handler_Stub &reply_handler_stub); diff --git a/TAO/tao/operation_details.h b/TAO/tao/operation_details.h index f7ee74f340f..05c71072d6b 100644 --- a/TAO/tao/operation_details.h +++ b/TAO/tao/operation_details.h @@ -76,6 +76,7 @@ public: CORBA::ULong len, TAO::Argument **args = 0, CORBA::ULong num_args = 0, + CORBA::Boolean has_in_args = true, TAO::Exception_Data *ex_data = 0, CORBA::ULong ex_count = 0); @@ -88,6 +89,7 @@ public: /// Return the flag that indicates whether the operation has any /// arguments CORBA::Boolean argument_flag (void) const; + CORBA::Boolean in_argument_flag (void) const; /// Set the response flags void response_flags (CORBA::Octet flags); @@ -209,6 +211,9 @@ private: /// Number of arguments including the return value CORBA::ULong num_args_; + /// A flag indicating any args are sent with the request + CORBA::Boolean has_in_args_; + /// The type of exceptions that the operations can throw. TAO::Exception_Data *ex_data_; @@ -232,6 +237,7 @@ private: /// The optional reply dispatcher TAO_Reply_Dispatcher *reply_dispatcher_; + }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/operation_details.inl b/TAO/tao/operation_details.inl index 3c9d6f6a35e..cbd733b5838 100644 --- a/TAO/tao/operation_details.inl +++ b/TAO/tao/operation_details.inl @@ -9,6 +9,7 @@ TAO_Operation_Details::TAO_Operation_Details (const char *name, CORBA::ULong len, TAO::Argument **args, CORBA::ULong num, + CORBA::Boolean has_in_args, TAO::Exception_Data *data, CORBA::ULong count) : opname_ (name) @@ -18,6 +19,7 @@ TAO_Operation_Details::TAO_Operation_Details (const char *name, , addressing_mode_ (TAO_Target_Specification::Key_Addr) , args_ (args) , num_args_ (num) + , has_in_args_ (has_in_args) , ex_data_ (data) , ex_count_ (count) , use_stub_args_ (args ? true : false) @@ -48,6 +50,28 @@ TAO_Operation_Details::argument_flag (void) const return (this->num_args_ > 1); } +#if 1 +ACE_INLINE CORBA::Boolean +TAO_Operation_Details::in_argument_flag (void) const +{ + return this->has_in_args_ && this->num_args_ > 1; +} +#else +ACE_INLINE CORBA::Boolean +TAO_Operation_Details::in_argument_flag (void) const +{ + for (CORBA::ULong i = 1; i < this->num_args_ && !this->has_in_args_; i++) + { + if (dynamic_cast<TAO::InArgument *>(args_[i]) != 0 || + dynamic_cast<TAO::InoutArgument *>(args_[i])) + { + return true; + } + } + return false; +} +#endif // TAO_IGNORE_IN_ARGS + ACE_INLINE TAO_Service_Context & TAO_Operation_Details::request_service_context (void) { |