summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvzykov <vzykov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2008-04-01 14:17:09 +0000
committervzykov <vzykov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2008-04-01 14:17:09 +0000
commit1cae543544f2ba99c1c32bbf0932d9cfbf44f2fd (patch)
tree75c80e81433478444289a3e7a1671664a0657eac
parent928e221e44ce14a7ff089e0a92e62ebe9b4b3478 (diff)
downloadATCD-1cae543544f2ba99c1c32bbf0932d9cfbf44f2fd.tar.gz
ChangeLogTag: Tue Apr 1 14:11:00 UTC 2008 Vladimir Zykov <vladimir.zykov@prismtech.com>
-rw-r--r--TAO/ChangeLog24
-rw-r--r--TAO/tao/PortableServer/Object_Adapter.cpp2
-rw-r--r--TAO/tests/Bug_3276_Regression/Manager.cpp10
-rw-r--r--TAO/tests/Bug_3276_Regression/Servant_Locator.cpp2
-rw-r--r--TAO/tests/Bug_3276_Regression/client.cpp5
-rw-r--r--TAO/tests/Collocated_Forwarding/Collocated_Forwarding.mpc24
-rw-r--r--TAO/tests/Collocated_Forwarding/Server_ORBInitializer.cpp53
-rw-r--r--TAO/tests/Collocated_Forwarding/Server_ORBInitializer.h64
-rw-r--r--TAO/tests/Collocated_Forwarding/Server_Request_Interceptor.cpp99
-rw-r--r--TAO/tests/Collocated_Forwarding/Server_Request_Interceptor.h83
-rwxr-xr-xTAO/tests/Collocated_Forwarding/run_test.pl31
-rw-r--r--TAO/tests/Collocated_Forwarding/server.cpp171
-rw-r--r--TAO/tests/Collocated_Forwarding/test.idl20
-rw-r--r--TAO/tests/Collocated_Forwarding/test_i.cpp54
-rw-r--r--TAO/tests/Collocated_Forwarding/test_i.h52
15 files changed, 686 insertions, 8 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index 341ffecb8d2..016ba011013 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,27 @@
+Tue Apr 1 14:11:00 UTC 2008 Vladimir Zykov <vladimir.zykov@prismtech.com>
+
+ * tao/PortableServer/Object_Adapter.cpp:
+ Fixed a memory leak that was happening because a forward
+ reference was duplicated twice.
+
+ * tests/Collocated_Forwarding/Server_ORBInitializer.h:
+ * tests/Collocated_Forwarding/Server_Request_Interceptor.h:
+ * tests/Collocated_Forwarding/test.idl:
+ * tests/Collocated_Forwarding/server.cpp:
+ * tests/Collocated_Forwarding/test_i.cpp:
+ * tests/Collocated_Forwarding/Collocated_Forwarding.mpc:
+ * tests/Collocated_Forwarding/Server_ORBInitializer.cpp:
+ * tests/Collocated_Forwarding/Server_Request_Interceptor.cpp:
+ * tests/Collocated_Forwarding/run_test.pl:
+ * tests/Collocated_Forwarding/test_i.h:
+ Added a new test for collocated forwarding case.
+ For details see Bug#3276.
+
+ * tests/Bug_3276_Regression/client.cpp:
+ * tests/Bug_3276_Regression/Servant_Locator.cpp:
+ * tests/Bug_3276_Regression/Manager.cpp:
+ Changed main to ACE_TMAIN.
+
Tue Apr 1 13:17:12 UTC 2008 Johnny Willemsen <jwillemsen@remedy.nl>
* examples/Load_Balancing/run_test.pl:
diff --git a/TAO/tao/PortableServer/Object_Adapter.cpp b/TAO/tao/PortableServer/Object_Adapter.cpp
index 91c3d86e308..c8ce36d03ee 100644
--- a/TAO/tao/PortableServer/Object_Adapter.cpp
+++ b/TAO/tao/PortableServer/Object_Adapter.cpp
@@ -382,7 +382,7 @@ TAO_Object_Adapter::dispatch_servant (const TAO::ObjectKey &key,
// calling operation's mem-space.
if (req.collocated() && req.pi_reply_status () == PortableInterceptor::LOCATION_FORWARD)
{
- forward_to = CORBA::Object::_duplicate (req.forward_location ());
+ forward_to = req.forward_location ();
result = TAO_Adapter::DS_FORWARD;
}
#endif
diff --git a/TAO/tests/Bug_3276_Regression/Manager.cpp b/TAO/tests/Bug_3276_Regression/Manager.cpp
index 35d3167fd10..78b73ffa0d5 100644
--- a/TAO/tests/Bug_3276_Regression/Manager.cpp
+++ b/TAO/tests/Bug_3276_Regression/Manager.cpp
@@ -31,7 +31,7 @@ parse_args (int argc, char *argv[])
}
int
-main (int argc, char *argv[])
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
try
{
@@ -55,7 +55,9 @@ main (int argc, char *argv[])
if (proxy_ior != 0)
{
- ACE_DEBUG ((LM_DEBUG, "Writing the servant locator object ref out to file %s\n", proxy_ior));
+ ACE_DEBUG ((LM_DEBUG,
+ "Writing the servant locator object ref out to file %s\n",
+ proxy_ior));
output_file = ACE_OS::fopen (proxy_ior, "w");
if (output_file == 0)
ACE_ERROR_RETURN ((LM_ERROR,
@@ -79,7 +81,9 @@ main (int argc, char *argv[])
// If the proxy_ior exists, output the ior to it
if (control_ior != 0)
{
- ACE_DEBUG ((LM_DEBUG, "Writing the root poa servant server IOR out to file %s\n", control_ior));
+ ACE_DEBUG ((LM_DEBUG,
+ "Writing the root poa servant server IOR out to file %s\n",
+ control_ior));
output_file = ACE_OS::fopen (control_ior, "w");
if (output_file == 0)
ACE_ERROR_RETURN ((LM_ERROR,
diff --git a/TAO/tests/Bug_3276_Regression/Servant_Locator.cpp b/TAO/tests/Bug_3276_Regression/Servant_Locator.cpp
index 580776adf3e..697deb9ea8f 100644
--- a/TAO/tests/Bug_3276_Regression/Servant_Locator.cpp
+++ b/TAO/tests/Bug_3276_Regression/Servant_Locator.cpp
@@ -5,8 +5,6 @@
#include "testC.h"
#include "ace/OS_NS_string.h"
-ACE_RCSID(Forwarding, Servant_Locator, "$Id$")
-
PortableServer::Servant
Servant_Locator::preinvoke (const PortableServer::ObjectId & /* oid */,
PortableServer::POA_ptr /* poa_ptr */,
diff --git a/TAO/tests/Bug_3276_Regression/client.cpp b/TAO/tests/Bug_3276_Regression/client.cpp
index c0fb9eb32ab..e2ef060d28c 100644
--- a/TAO/tests/Bug_3276_Regression/client.cpp
+++ b/TAO/tests/Bug_3276_Regression/client.cpp
@@ -39,7 +39,7 @@ parse_args (int argc, char *argv[])
}
int
-main (int argc, char *argv[])
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
try
{
@@ -84,7 +84,8 @@ main (int argc, char *argv[])
if (m == TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE &&
ex.completed () == CORBA::COMPLETED_NO)
{
- ACE_DEBUG ((LM_DEBUG, "TRANSIENT caught in client as it was expected.\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ "TRANSIENT caught in client as it was expected.\n"));
}
else
{
diff --git a/TAO/tests/Collocated_Forwarding/Collocated_Forwarding.mpc b/TAO/tests/Collocated_Forwarding/Collocated_Forwarding.mpc
new file mode 100644
index 00000000000..4eb17dee618
--- /dev/null
+++ b/TAO/tests/Collocated_Forwarding/Collocated_Forwarding.mpc
@@ -0,0 +1,24 @@
+// -*- MPC -*-
+// $Id$
+
+project(*idl): taoidldefaults {
+ IDL_Files {
+ idlflags += -Gd -Sorb
+ test.idl
+ }
+ custom_only = 1
+}
+
+project(*Server): taoserver, orbsvcsexe, iormanip, pi_server, messaging {
+ after += *idl
+ Source_Files {
+ test_i.cpp
+ testC.cpp
+ testS.cpp
+ Server_ORBInitializer.cpp
+ Server_Request_Interceptor.cpp
+ server.cpp
+ }
+ IDL_Files {
+ }
+}
diff --git a/TAO/tests/Collocated_Forwarding/Server_ORBInitializer.cpp b/TAO/tests/Collocated_Forwarding/Server_ORBInitializer.cpp
new file mode 100644
index 00000000000..76548d1dc1f
--- /dev/null
+++ b/TAO/tests/Collocated_Forwarding/Server_ORBInitializer.cpp
@@ -0,0 +1,53 @@
+// -*- C++ -*-
+
+#include "Server_ORBInitializer.h"
+#include "tao/ORB_Constants.h"
+
+ACE_RCSID (Collocated_Forwarding,
+ Server_ORBInitializer,
+ "$Id$")
+
+#if TAO_HAS_INTERCEPTORS == 1
+
+#include "Server_Request_Interceptor.h"
+
+Server_ORBInitializer::Server_ORBInitializer (CORBA::ULong request_pass_count)
+ : request_pass_count_ (request_pass_count)
+ , server_interceptor_ ()
+{
+}
+
+void
+Server_ORBInitializer::pre_init (
+ PortableInterceptor::ORBInitInfo_ptr)
+{
+}
+
+void
+Server_ORBInitializer::post_init (
+ PortableInterceptor::ORBInitInfo_ptr info)
+{
+ PortableInterceptor::ServerRequestInterceptor_ptr interceptor;
+ // Install the server request interceptor.
+ ACE_NEW_THROW_EX (interceptor,
+ Server_Request_Interceptor (this->request_pass_count_),
+ CORBA::NO_MEMORY (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+
+ this->server_interceptor_ = interceptor;
+
+ info->add_server_request_interceptor (interceptor);
+}
+
+PortableInterceptor::ServerRequestInterceptor_ptr
+Server_ORBInitializer::server_interceptor (void)
+{
+ return
+ PortableInterceptor::ServerRequestInterceptor::_duplicate (
+ this->server_interceptor_.in ());
+}
+
+#endif /* TAO_HAS_INTERCEPTORS == 1 */
diff --git a/TAO/tests/Collocated_Forwarding/Server_ORBInitializer.h b/TAO/tests/Collocated_Forwarding/Server_ORBInitializer.h
new file mode 100644
index 00000000000..ed018d5253f
--- /dev/null
+++ b/TAO/tests/Collocated_Forwarding/Server_ORBInitializer.h
@@ -0,0 +1,64 @@
+// -*- C++ -*-
+
+#ifndef TAO_SERVER_ORB_INITIALIZER_H
+#define TAO_SERVER_ORB_INITIALIZER_H
+
+#include /**/ "ace/pre.h"
+
+#include "tao/LocalObject.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if TAO_HAS_INTERCEPTORS == 1
+
+#include "tao/PI/PI.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 */
+
+// Forward declaration.
+class Server_Request_Interceptor;
+
+/// Server side ORB initializer.
+class Server_ORBInitializer :
+ public virtual PortableInterceptor::ORBInitializer,
+ public virtual TAO_Local_RefCounted_Object
+{
+public:
+
+ /// Constructor.
+ Server_ORBInitializer (CORBA::ULong request_pass_count);
+
+ virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr info);
+
+ virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info);
+
+ /// Return the created server request interceptor. Only valid after
+ /// post_init(), i.e. ORB_init(), has been called.
+ PortableInterceptor::ServerRequestInterceptor_ptr server_interceptor (void);
+
+private:
+
+ /// How much requests to pass thru before forwarding.
+ CORBA::ULong request_pass_count_;
+
+ /// Pointer to the server request interceptor. ORB is responsible
+ /// for storage.
+ PortableInterceptor::ServerRequestInterceptor_var server_interceptor_;
+};
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif /* _MSC_VER */
+
+#endif /* TAO_HAS_INTERCEPTORS == 1 */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_SERVER_ORB_INITIALIZER_H */
diff --git a/TAO/tests/Collocated_Forwarding/Server_Request_Interceptor.cpp b/TAO/tests/Collocated_Forwarding/Server_Request_Interceptor.cpp
new file mode 100644
index 00000000000..2602da3ff9e
--- /dev/null
+++ b/TAO/tests/Collocated_Forwarding/Server_Request_Interceptor.cpp
@@ -0,0 +1,99 @@
+// -*- C++ -*-
+
+#include "Server_Request_Interceptor.h"
+#include "tao/PI_Server/PI_Server.h"
+#include "tao/ORB_Constants.h"
+#include "tao/CDR.h"
+#include "testS.h"
+
+ACE_RCSID (Collocated_Forwarding,
+ Server_Request_Interceptor,
+ "$Id$")
+
+//static const CORBA::ULong expected_version = 5;
+
+Server_Request_Interceptor::Server_Request_Interceptor (CORBA::ULong request_pass_count)
+ : request_pass_count_ (request_pass_count)
+ , request_count_ (0)
+ , to_ (CORBA::Object::_nil ())
+{
+}
+
+void
+Server_Request_Interceptor::forward (
+ CORBA::Object_ptr to)
+{
+ if (CORBA::is_nil (to))
+ throw CORBA::INV_OBJREF (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ EINVAL),
+ CORBA::COMPLETED_NO);
+
+ char *argv[] = {NULL};
+ int argc = 0;
+
+ // Fetch the ORB having been initialized in main()
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "Server ORB");
+
+ CORBA::String_var s_to = orb->object_to_string (to);
+
+ this->to_ = orb->string_to_object (s_to.in ());
+}
+
+char *
+Server_Request_Interceptor::name (void)
+{
+ return CORBA::string_dup ("Server_Request_Interceptor");
+}
+
+void
+Server_Request_Interceptor::destroy (void)
+{
+ CORBA::release (this->to_);
+}
+
+void
+Server_Request_Interceptor::receive_request_service_contexts (
+ PortableInterceptor::ServerRequestInfo_ptr)
+{
+ this->request_count_++;
+}
+
+void
+Server_Request_Interceptor::receive_request (
+ PortableInterceptor::ServerRequestInfo_ptr)
+{
+ if (this->request_count_ == this->request_pass_count_)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "SERVER: Request %d will be forwarded "
+ "to object 'to'\nSERVER: via "
+ "receive_request_service_contexts().\n",
+ this->request_count_));
+
+ // Throw forward exception
+ throw PortableInterceptor::ForwardRequest (this->to_);
+ }
+
+ return;
+}
+
+void
+Server_Request_Interceptor::send_reply (
+ PortableInterceptor::ServerRequestInfo_ptr)
+{
+}
+
+void
+Server_Request_Interceptor::send_exception (
+ PortableInterceptor::ServerRequestInfo_ptr)
+{
+}
+
+void
+Server_Request_Interceptor::send_other (
+ PortableInterceptor::ServerRequestInfo_ptr)
+{
+}
diff --git a/TAO/tests/Collocated_Forwarding/Server_Request_Interceptor.h b/TAO/tests/Collocated_Forwarding/Server_Request_Interceptor.h
new file mode 100644
index 00000000000..8f3a9e65ba1
--- /dev/null
+++ b/TAO/tests/Collocated_Forwarding/Server_Request_Interceptor.h
@@ -0,0 +1,83 @@
+// -*- C++ -*-
+
+#ifndef SERVER_REQUEST_INTERCEPTOR_H
+#define SERVER_REQUEST_INTERCEPTOR_H
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "testC.h"
+#include "tao/LocalObject.h"
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4250)
+#endif /* _MSC_VER */
+
+/**
+ * @class Server_Request_Interceptor
+ *
+ * @brief Simple concrete server request interceptor.
+ */
+class Server_Request_Interceptor
+ : public virtual Collocated_ForwardRequestTest::ServerRequestInterceptor,
+ public virtual TAO_Local_RefCounted_Object
+{
+public:
+
+ /// Constructor.
+ Server_Request_Interceptor (CORBA::ULong request_pass_count);
+
+ /// Set the references to which requests will be forwarded.
+ virtual void forward (CORBA::Object_ptr to);
+
+ /**
+ * @name Methods Required by the Server Request Interceptor
+ * Interface
+ *
+ * These are methods that must be implemented since they are pure
+ * virtual in the abstract base class. They are the canonical
+ * methods required for all server request interceptors.
+ */
+ //@{
+ /// Return the name of this ServerRequestinterceptor.
+ virtual char * name (void);
+
+ virtual void destroy (void);
+
+ virtual void receive_request_service_contexts (
+ PortableInterceptor::ServerRequestInfo_ptr ri);
+
+ virtual void receive_request (
+ PortableInterceptor::ServerRequestInfo_ptr ri);
+
+ virtual void send_reply (
+ PortableInterceptor::ServerRequestInfo_ptr ri);
+
+ virtual void send_exception (
+ PortableInterceptor::ServerRequestInfo_ptr ri);
+
+ virtual void send_other (
+ PortableInterceptor::ServerRequestInfo_ptr ri);
+ //@}
+
+private:
+
+ /// How much requests to pass thru before forwarding.
+ CORBA::ULong request_pass_count_;
+
+ /// The number of requests intercepted by this interceptor.
+ CORBA::ULong request_count_;
+
+ /// References to the object used in this test.
+ CORBA::Object_ptr to_;
+};
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif /* _MSC_VER */
+
+#endif /* SERVER_REQUEST_INTERCEPTOR_H */
diff --git a/TAO/tests/Collocated_Forwarding/run_test.pl b/TAO/tests/Collocated_Forwarding/run_test.pl
new file mode 100755
index 00000000000..7ae4665d890
--- /dev/null
+++ b/TAO/tests/Collocated_Forwarding/run_test.pl
@@ -0,0 +1,31 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::Run_Test;
+
+print "Run sever with direct collocation strategy\n";
+
+$SV2 = new PerlACE::Process ("server", "-d -ORBCollocationStrategy direct");
+
+$server2 = $SV2->SpawnWaitKill (10);
+if ($server2 != 0) {
+ print STDERR "Server with direct collocation strategy return status = $server2\n";
+ exit 1;
+}
+
+print "Run sever with pass thru collocation strategy\n";
+
+$SV1 = new PerlACE::Process ("server", "");
+
+$server1 = $SV1->SpawnWaitKill (10);
+if ($server1 != 0) {
+ print STDERR "Server with thru poa collocation strategy return status = $server1\n";
+ exit 1;
+}
+
+exit 0;
diff --git a/TAO/tests/Collocated_Forwarding/server.cpp b/TAO/tests/Collocated_Forwarding/server.cpp
new file mode 100644
index 00000000000..b9622ad2521
--- /dev/null
+++ b/TAO/tests/Collocated_Forwarding/server.cpp
@@ -0,0 +1,171 @@
+// -*- C++ -*-
+
+#include "ace/Get_Opt.h"
+#include "test_i.h"
+#include "ace/OS_NS_stdio.h"
+
+#if TAO_HAS_INTERCEPTORS
+
+#include "Server_ORBInitializer.h"
+#include "Server_Request_Interceptor.h"
+#include "tao/IORManipulation/IORManipulation.h"
+#include "tao/ORBInitializer_Registry.h"
+
+ACE_RCSID (Collocated_Forwarding,
+ server,
+ "$Id$")
+
+const CORBA::ULong passes_before_forward = 6;
+
+bool direct_collocation = false;
+
+int
+parse_args (int argc, char *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "d");
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'd':
+ direct_collocation = true;
+ break;
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Usage: %s "
+ "-d\n",
+ argv[0]),
+ -1);
+ }
+
+ return 0;
+}
+
+void test_colocal (Collocated_ForwardRequestTest::test_ptr server)
+{
+ CORBA::ULong number = 0;
+ for (int i = 1; i <= 10; ++i)
+ {
+ ACE_DEBUG ((LM_INFO,
+ "CLIENT: Issuing colocal request %d.\n",
+ i));
+ CORBA::ULong retval =
+ server->collocated_call ();
+
+ number += retval;
+ }
+
+ if (number != 15)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) ERROR: Did not forward to new location\n"));
+ ACE_OS::abort ();
+ }
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ Server_ORBInitializer *temp_initializer = 0;
+ ACE_NEW_RETURN (temp_initializer,
+ Server_ORBInitializer (passes_before_forward),
+ -1); // No exceptions yet!
+ PortableInterceptor::ORBInitializer_var orb_initializer =
+ temp_initializer;
+
+ PortableInterceptor::register_orb_initializer (orb_initializer.in ());
+
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "Server ORB");
+
+ if (::parse_args (argc, argv) != 0)
+ return -1;
+
+ 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 ();
+
+ test_i servant1 (1, direct_collocation, orb.in ());
+ test_i servant2 (2, direct_collocation, orb.in ());
+
+ PortableServer::ObjectId_var oid1 =
+ root_poa->activate_object (&servant1);
+
+ PortableServer::ObjectId_var oid2 =
+ root_poa->activate_object (&servant2);
+
+ CORBA::Object_var obj1 =
+ root_poa->servant_to_reference (&servant1);
+
+ CORBA::Object_var obj2 =
+ root_poa->servant_to_reference (&servant2);
+
+ poa_manager->activate ();
+
+ // Set the forward references in the server request interceptor.
+ PortableInterceptor::ServerRequestInterceptor_var
+ server_interceptor = temp_initializer->server_interceptor ();
+
+ Collocated_ForwardRequestTest::ServerRequestInterceptor_var interceptor =
+ Collocated_ForwardRequestTest::ServerRequestInterceptor::_narrow (
+ server_interceptor.in ());
+
+ if (CORBA::is_nil (interceptor.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Could not obtain reference to "
+ "server request interceptor.\n"),
+ -1);
+
+ if (direct_collocation)
+ {
+ servant1.forward (obj2.in (), passes_before_forward);
+ }
+ else
+ {
+ interceptor->forward (obj2.in ());
+ }
+
+ // Run co-local test
+ {
+ Collocated_ForwardRequestTest::test_var server =
+ Collocated_ForwardRequestTest::test::_narrow (obj1.in ());
+ test_colocal (server.in ());
+ }
+
+ root_poa->destroy (1, 1);
+
+ orb->destroy ();
+
+ ACE_DEBUG ((LM_DEBUG, "Event loop finished.\n"));
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Caught exception:");
+ return -1;
+ }
+
+ return 0;
+}
+
+#else
+
+int
+ACE_TMAIN(int, ACE_TCHAR *[])
+{
+ return 0;
+}
+
+#endif /* TAO_HAS_INTERCEPTORS */
diff --git a/TAO/tests/Collocated_Forwarding/test.idl b/TAO/tests/Collocated_Forwarding/test.idl
new file mode 100644
index 00000000000..b141b4afb32
--- /dev/null
+++ b/TAO/tests/Collocated_Forwarding/test.idl
@@ -0,0 +1,20 @@
+// -*- IDL -*-
+//$Id$
+
+#include "tao/PortableInterceptor.pidl"
+#include "tao/PI_Server/PI_Server_include.pidl"
+
+module Collocated_ForwardRequestTest
+{
+ interface test
+ {
+ short collocated_call ();
+ };
+
+ local interface ServerRequestInterceptor
+ : PortableInterceptor::ServerRequestInterceptor
+ {
+ /// Set the references to which requests will be forwarded.
+ void forward (in Object to);
+ };
+};
diff --git a/TAO/tests/Collocated_Forwarding/test_i.cpp b/TAO/tests/Collocated_Forwarding/test_i.cpp
new file mode 100644
index 00000000000..a76b0fb8cff
--- /dev/null
+++ b/TAO/tests/Collocated_Forwarding/test_i.cpp
@@ -0,0 +1,54 @@
+// -*- C++ -*-
+
+#include "test_i.h"
+#include "tao/PortableServer/ForwardRequestC.h"
+
+ACE_RCSID (Collocated_Forwarding,
+ test_i,
+ "$Id$")
+
+test_i::test_i (CORBA::Short id,
+ bool direct,
+ CORBA::ORB_ptr orb)
+ : id_ (id)
+ , direct_ (direct)
+ , orb_ (CORBA::ORB::_duplicate (orb))
+ , to_ (CORBA::Object::_nil ())
+ , request_pass_count_ (0)
+ , request_count_ (0)
+{
+}
+
+void
+test_i::forward (CORBA::Object_ptr to,
+ CORBA::ULong request_pass_count)
+{
+ this->to_ = CORBA::Object::_duplicate (to);
+ this->request_pass_count_ = request_pass_count;
+}
+
+CORBA::Short
+test_i::collocated_call (void)
+{
+ this->request_count_++;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Collocated call is executed in object with id %d.\n",
+ this->id_));
+
+ if (!CORBA::is_nil (this->to_.in ()))
+ {
+ if (this->request_count_ == this->request_pass_count_)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "SERVER: Request %d will be forwarded "
+ "to object 'to'\nSERVER: via collocated_call().\n",
+ this->request_count_));
+
+ // Throw forward exception
+ throw PortableServer::ForwardRequest (this->to_.in ());
+ }
+ }
+
+ return this->id_;
+}
diff --git a/TAO/tests/Collocated_Forwarding/test_i.h b/TAO/tests/Collocated_Forwarding/test_i.h
new file mode 100644
index 00000000000..d96d3b8cf21
--- /dev/null
+++ b/TAO/tests/Collocated_Forwarding/test_i.h
@@ -0,0 +1,52 @@
+// -*- C++ -*-
+
+#ifndef TEST_I_H
+#define TEST_I_H
+
+#include "testS.h"
+
+/**
+ * @class test_i
+ *
+ * @brief Simple test class.
+ *
+ * This class implements the "test" interface used in this test.
+ */
+class test_i : public virtual POA_Collocated_ForwardRequestTest::test
+{
+public:
+
+ /// Constructor.
+ test_i (CORBA::Short id,
+ bool direct,
+ CORBA::ORB_ptr orb);
+
+ /// A way to setup forwarding in case of direct collocation.
+ void forward (CORBA::Object_ptr to,
+ CORBA::ULong request_pass_count);
+
+ /// Return the number assigned to this object.
+ virtual CORBA::Short collocated_call (void);
+
+private:
+
+ /// Id of this instance.
+ CORBA::Short id_;
+
+ /// An indication to throwing forward request exception.
+ bool direct_;
+
+ /// Pseudo-reference to the ORB.
+ CORBA::ORB_var orb_;
+
+ /// A place where to forward.
+ CORBA::Object_var to_;
+
+ /// How much requests to pass thru before forwarding.
+ CORBA::ULong request_pass_count_;
+
+ /// The number of requests intercepted by this interceptor.
+ CORBA::ULong request_count_;
+};
+
+#endif /* TEST_I_H */