summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TAO/ChangeLog33
-rw-r--r--TAO/NEWS7
-rw-r--r--TAO/TAO_IDL/ast/ast_operation.cpp17
-rw-r--r--TAO/TAO_IDL/be/be_visitor_operation/ami_cs.cpp7
-rw-r--r--TAO/TAO_IDL/be/be_visitor_operation/operation.cpp15
-rw-r--r--TAO/TAO_IDL/include/ast_operation.h6
-rw-r--r--TAO/interop-tests/CdrOutArg/README17
-rw-r--r--TAO/interop-tests/CdrOutArg/coa.mwc4
-rw-r--r--TAO/interop-tests/CdrOutArg/idl/test.idl32
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/CdrOutArg.mpc44
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/Client_ORBInitializer.cpp40
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/Client_ORBInitializer.h44
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/Server_ORBInitializer.cpp36
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/Server_ORBInitializer.h44
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/client.cpp91
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/client_interceptor.cpp121
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/client_interceptor.h63
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/server.cpp121
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/server_interceptor.cpp92
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/server_interceptor.h58
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/test_i.cpp20
-rw-r--r--TAO/interop-tests/CdrOutArg/tao/test_i.h42
-rw-r--r--TAO/tao/GIOP_Message_Generator_Parser_12.cpp2
-rw-r--r--TAO/tao/Invocation_Adapter.cpp1
-rw-r--r--TAO/tao/Invocation_Adapter.h5
-rw-r--r--TAO/tao/Invocation_Adapter.inl4
-rw-r--r--TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp6
-rw-r--r--TAO/tao/Messaging/Asynch_Invocation_Adapter.h3
-rw-r--r--TAO/tao/operation_details.h6
-rw-r--r--TAO/tao/operation_details.inl24
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:
diff --git a/TAO/NEWS b/TAO/NEWS
index 07ece43dda4..440d255b469 100644
--- a/TAO/NEWS
+++ b/TAO/NEWS
@@ -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)
{