summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriliyan <iliyan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2006-12-19 22:32:59 +0000
committeriliyan <iliyan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2006-12-19 22:32:59 +0000
commit27d5d06f8d192e0a4fad8f8a030f52d70516a4e3 (patch)
tree3dfcfed8fb554671350f4734498e1c4b19c5b7d7
parentdc876d2f697cccb1f680582f2dbd379af781ffb9 (diff)
downloadATCD-27d5d06f8d192e0a4fad8f8a030f52d70516a4e3.tar.gz
ChangeLogTag: Tue Dec 19 22:09:34 UTC 2006 Iliyan Jeliazkov <iliyan@ociweb.com>
-rw-r--r--TAO/ChangeLog205
-rw-r--r--TAO/docs/transport_current/index.html488
-rw-r--r--TAO/docs/transport_current/transport_current.css31
-rw-r--r--TAO/tao/ORB_Core.h3
-rw-r--r--TAO/tao/Profile_Transport_Resolver.cpp23
-rw-r--r--TAO/tao/Profile_Transport_Resolver.h6
-rw-r--r--TAO/tao/Profile_Transport_Resolver.inl2
-rw-r--r--TAO/tao/TAO_Server_Request.cpp3
-rw-r--r--TAO/tao/TAO_Server_Request.h5
-rw-r--r--TAO/tao/TAO_Server_Request.inl1
-rw-r--r--TAO/tao/TSS_Resources.cpp4
-rw-r--r--TAO/tao/TSS_Resources.h12
-rw-r--r--TAO/tao/Transport.cpp39
-rw-r--r--TAO/tao/Transport.h69
-rw-r--r--TAO/tao/Transport.inl67
-rw-r--r--TAO/tao/TransportCurrent/Current_Impl.cpp106
-rw-r--r--TAO/tao/TransportCurrent/Current_Impl.h123
-rw-r--r--TAO/tao/TransportCurrent/Current_Loader.cpp155
-rw-r--r--TAO/tao/TransportCurrent/Current_Loader.h91
-rw-r--r--TAO/tao/TransportCurrent/Current_ORBInitializer.cpp51
-rw-r--r--TAO/tao/TransportCurrent/Current_ORBInitializer.h65
-rw-r--r--TAO/tao/TransportCurrent/Current_ORBInitializer_Base.cpp75
-rw-r--r--TAO/tao/TransportCurrent/Current_ORBInitializer_Base.h69
-rw-r--r--TAO/tao/TransportCurrent/IIOP_Current_Impl.cpp124
-rw-r--r--TAO/tao/TransportCurrent/IIOP_Current_Impl.h108
-rw-r--r--TAO/tao/TransportCurrent/IIOP_Current_Loader.cpp95
-rw-r--r--TAO/tao/TransportCurrent/IIOP_Current_Loader.h68
-rw-r--r--TAO/tao/TransportCurrent/IIOP_Transport_Current.h17
-rw-r--r--TAO/tao/TransportCurrent/TC.idl57
-rw-r--r--TAO/tao/TransportCurrent/TC.mpc33
-rw-r--r--TAO/tao/TransportCurrent/TC_IIOP.idl56
-rw-r--r--TAO/tao/TransportCurrent/TC_IIOP.mpc27
-rw-r--r--TAO/tao/TransportCurrent/Transport_Current.h16
-rw-r--r--TAO/tao/TransportCurrent/Transport_Current_Export.h54
-rw-r--r--TAO/tao/Transport_Selection_Guard.cpp81
-rw-r--r--TAO/tao/Transport_Selection_Guard.h125
-rw-r--r--TAO/tao/orbconf.h6
-rw-r--r--TAO/tao/tao.mpc2
-rw-r--r--TAO/tests/TransportCurrent/Framework/Client_Request_Interceptor.cpp182
-rw-r--r--TAO/tests/TransportCurrent/Framework/Client_Request_Interceptor.h144
-rw-r--r--TAO/tests/TransportCurrent/Framework/Current_Test.idl34
-rw-r--r--TAO/tests/TransportCurrent/Framework/Current_Test_Impl.cpp169
-rw-r--r--TAO/tests/TransportCurrent/Framework/Current_Test_Impl.h80
-rw-r--r--TAO/tests/TransportCurrent/Framework/Framework.mpc27
-rw-r--r--TAO/tests/TransportCurrent/Framework/ORBInitializer_T.h62
-rw-r--r--TAO/tests/TransportCurrent/Framework/README22
-rw-r--r--TAO/tests/TransportCurrent/Framework/Server_Main.cpp23
-rw-r--r--TAO/tests/TransportCurrent/Framework/Server_Request_Interceptor.cpp164
-rw-r--r--TAO/tests/TransportCurrent/Framework/Server_Request_Interceptor.h139
-rw-r--r--TAO/tests/TransportCurrent/Framework/Tester.cpp70
-rw-r--r--TAO/tests/TransportCurrent/Framework/client-static.conf1
-rw-r--r--TAO/tests/TransportCurrent/Framework/client.conf1
-rw-r--r--TAO/tests/TransportCurrent/Framework/client.cpp287
-rwxr-xr-xTAO/tests/TransportCurrent/Framework/run_test.pl59
-rw-r--r--TAO/tests/TransportCurrent/Framework/server-static.conf1
-rw-r--r--TAO/tests/TransportCurrent/Framework/server.conf1
-rw-r--r--TAO/tests/TransportCurrent/Framework/server.cpp240
-rw-r--r--TAO/tests/TransportCurrent/Framework/simple.cpp86
-rw-r--r--TAO/tests/TransportCurrent/IIOP/Current_Test_Impl.cpp139
-rw-r--r--TAO/tests/TransportCurrent/IIOP/IIOP.mpc42
-rw-r--r--TAO/tests/TransportCurrent/IIOP/IIOP_Server_Main.cpp23
-rw-r--r--TAO/tests/TransportCurrent/IIOP/IIOP_Server_Request_Interceptor.cpp323
-rw-r--r--TAO/tests/TransportCurrent/IIOP/IIOP_Server_Request_Interceptor.h162
-rw-r--r--TAO/tests/TransportCurrent/IIOP/IIOP_Tester.cpp81
-rw-r--r--TAO/tests/TransportCurrent/IIOP/README25
-rw-r--r--TAO/tests/TransportCurrent/IIOP/client_dynamic.conf3
-rw-r--r--TAO/tests/TransportCurrent/IIOP/client_static.conf3
-rwxr-xr-xTAO/tests/TransportCurrent/IIOP/run_test.pl71
-rw-r--r--TAO/tests/TransportCurrent/IIOP/server_dynamic.conf2
-rw-r--r--TAO/tests/TransportCurrent/IIOP/server_static.conf2
70 files changed, 5206 insertions, 24 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index 09f92faa63a..7f7da97aa7e 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,208 @@
+Tue Dec 19 22:09:34 UTC 2006 Iliyan Jeliazkov <iliyan@ociweb.com>
+
+ Introducing the Transport::Current - an optional feature with an
+ IDL interface, which enables users to obtain information about
+ the Transports used to send or receive a message.
+
+ The implementation uses a TSS based stack of pointers to
+ Transport class instances, which an ORB selects on the critical
+ path. The structure is used to update message and endpoint
+ related statistical information for the correct Transport. An
+ IDL interface available through ORB::resolve_initial_references,
+ provides access to the accumulated data inside servant up-calls
+ and interceptor invocations.
+
+ * docs/transport_current:
+
+ A new directory for the Transport Current documentation to
+ inhabit.
+
+ * docs/transport_current/index.html:
+ * docs/transport_current/transport_current.css:
+
+ Added reference and user-guide documentation for the Transport
+ Current.
+
+ * tao/orbconf.h:
+
+ Enabled the Transport::Current feature by default, by defining
+ TAO_HAS_TRANSPORT_CURRENT. In recognition that this is very
+ likely an overkill for everybody but the few interested in the
+ feature, the plan is to reverse this default before the next
+ beta release.
+
+ * tao/ORB_Core.h:
+ * tao/Profile_Transport_Resolver.h:
+ * tao/Profile_Transport_Resolver.inl:
+ * tao/Profile_Transport_Resolver.cpp:
+
+ Replaced the "naked" Transport pointer with a smart-pointer-like
+ TAO::Transport_Selection_Guard, which has ctor and dtor that
+ help keep a TSS-based stack of Transport instances when
+ TAO_HAS_TRANSPORT_CURRENT is defined as 1. If the latter is
+ disabled, the TSS access overhead goes away.
+
+ * tao/TAO_Server_Request.h:
+ * tao/TAO_Server_Request.inl:
+ * tao/TAO_Server_Request.cpp:
+
+ Similar to the client-side code in Profile_Transport_Resolver,
+ this is where the server-side pieces of Transport Current
+ functionality plugs in. A Server_Request encapsulates knowledge
+ about the specific Transport on which an invocation
+ arrived. Adding a Transport_Selection_Guard instance member
+ (transport_selection_guard_) to keep track of the current
+ Transport, using TSS. This overhead is only present when
+ TAO_HAS_TRANSPORT_CURRENT is defined as 1.
+
+ * tao/TSS_Resources.h:
+ * tao/TSS_Resources.cpp:
+
+ Adding a Transport_Selection_Guard member pointer tsg_, which
+ when Transport Current feature is enabled, always points to the
+ most-recently selected (incoming or outgoing) Transport in the
+ current thread. This overhead is only present when
+ TAO_HAS_TRANSPORT_CURRENT is defined as 1.
+
+ * tao/Transport.h:
+ * tao/Transport.inl:
+ * tao/Transport.cpp (send_message_shared_i):
+
+ Introduced a new class TAO::Transport::Stats and added a member
+ pointer of that base type to the declaration of Transport. It
+ can only be non-null when Transport Current is enabled, whereby
+ it points to a TAO::Transport::Stats. The send_message_shared_i
+ has been modified to update the statistics. Also added the
+ requisite mutators and successor's.
+
+ * tao/Transport_Selection_Guard.h:
+ * tao/Transport_Selection_Guard.cpp:
+
+ The implementation of the TSS-pointed, stack-like chain of
+ Transport instances selected (potentially, in multiple nested up
+ calls). The TSS overhead is only present when
+ TAO_HAS_TRANSPORT_CURRENT is defined as 1, otherwise the methods
+ are trivial.
+
+ * tao/tao.mpc:
+
+ Updated to include the new source files.
+
+ * tao/TransportCurrent:
+
+ A new directory for the Transport Current implementation to
+ inhabit. Currently, there are two implementations: a generic
+ one and an IIOP-specific one. The reason these two share this
+ location is that the generic Current is too generic to be useful
+ on its own, while providing almost all the required
+ infrastructure for the IIOP-specific one.
+
+ * tao/TransportCurrent/Current_Impl.h:
+ * tao/TransportCurrent/Current_Impl.cpp:
+
+ The generic Current implementation.
+
+ * tao/TransportCurrent/Current_Loader.h:
+ * tao/TransportCurrent/Current_Loader.cpp:
+
+ A loader, to handle registration with the Service repository.
+
+ * tao/TransportCurrent/Current_ORBInitializer.h:
+ * tao/TransportCurrent/Current_ORBInitializer.cpp:
+ * tao/TransportCurrent/Current_ORBInitializer_Base.h:
+ * tao/TransportCurrent/Current_ORBInitializer_Base.cpp:
+
+ An ORB initializer, to handle the registration of the name for
+ which resolve_initial_references() will return you a Current
+ pointer.
+
+ * tao/TransportCurrent/IIOP_Current_Impl.h:
+ * tao/TransportCurrent/IIOP_Current_Impl.cpp:
+
+ The IIOP-specific Current implementation, complete with its own
+ derivative of TAO::Transport::Stats.
+
+ * tao/TransportCurrent/IIOP_Current_Loader.h:
+ * tao/TransportCurrent/IIOP_Current_Loader.cpp:
+
+ A loader, to handle registration with the Service repository.
+
+ * tao/TransportCurrent/IIOP_Transport_Current.h:
+
+ A client-side interface for the IIOP-specific Transport Current.
+
+ * tao/TransportCurrent/TC.idl:
+
+ A client-side interface for the generic Transport Current.
+
+ * tao/TransportCurrent/TC.mpc:
+
+ We need this to actually build the generic TC into a
+ self-contained service object library (DLL).
+
+ * tao/TransportCurrent/TC_IIOP.idl:
+
+ A client-side interface for the IIOP-specific Transport Current.
+
+ * tao/TransportCurrent/TC_IIOP.mpc:
+
+ We need this to actually build the IIOP-specific TC into a
+ self-contained service object library (DLL).
+
+ * tao/TransportCurrent/Transport_Current.h:
+
+ Basic declarations.
+
+ * tao/TransportCurrent/Transport_Current_Export.h:
+
+ Library export helpers.
+
+ * tests/TransportCurrent:
+
+ A new directory for the Transport Current tests to inhabit.
+
+ * tests/TransportCurrent/Framework:
+
+ A new directory for the test exercising the generic Transport Current.
+
+ * tests/TransportCurrent/Framework/Client_Request_Interceptor.h:
+ * tests/TransportCurrent/Framework/Client_Request_Interceptor.cpp:
+ * tests/TransportCurrent/Framework/Current_Test.idl:
+ * tests/TransportCurrent/Framework/Current_Test_Impl.h:
+ * tests/TransportCurrent/Framework/Current_Test_Impl.cpp:
+ * tests/TransportCurrent/Framework/Framework.mpc:
+ * tests/TransportCurrent/Framework/ORBInitializer_T.h:
+ * tests/TransportCurrent/Framework/README:
+ * tests/TransportCurrent/Framework/Server_Main.cpp:
+ * tests/TransportCurrent/Framework/Server_Request_Interceptor.h:
+ * tests/TransportCurrent/Framework/Server_Request_Interceptor.cpp:
+ * tests/TransportCurrent/Framework/Tester.cpp:
+ * tests/TransportCurrent/Framework/client-static.conf:
+ * tests/TransportCurrent/Framework/client.conf:
+ * tests/TransportCurrent/Framework/client.cpp:
+ * tests/TransportCurrent/Framework/run_test.pl:
+ * tests/TransportCurrent/Framework/server-static.conf:
+ * tests/TransportCurrent/Framework/server.conf:
+ * tests/TransportCurrent/Framework/server.cpp:
+ * tests/TransportCurrent/Framework/simple.cpp:
+
+ * tests/TransportCurrent/IIOP:
+
+ A new directory for the test exercising the IIOP-specific Transport Current.
+
+ * tests/TransportCurrent/IIOP/Current_Test_Impl.cpp:
+ * tests/TransportCurrent/IIOP/IIOP.mpc:
+ * tests/TransportCurrent/IIOP/IIOP_Server_Main.cpp:
+ * tests/TransportCurrent/IIOP/IIOP_Server_Request_Interceptor.h:
+ * tests/TransportCurrent/IIOP/IIOP_Server_Request_Interceptor.cpp:
+ * tests/TransportCurrent/IIOP/IIOP_Tester.cpp:
+ * tests/TransportCurrent/IIOP/README:
+ * tests/TransportCurrent/IIOP/client_dynamic.conf:
+ * tests/TransportCurrent/IIOP/client_static.conf:
+ * tests/TransportCurrent/IIOP/run_test.pl:
+ * tests/TransportCurrent/IIOP/server_dynamic.conf:
+ * tests/TransportCurrent/IIOP/server_static.conf:
+
Tue Dec 19 18:44:02 UTC 2006 J.T. Conklin <jtc@acorntoolworks.com>
* */Makefile.am:
diff --git a/TAO/docs/transport_current/index.html b/TAO/docs/transport_current/index.html
new file mode 100644
index 00000000000..40067cbdc35
--- /dev/null
+++ b/TAO/docs/transport_current/index.html
@@ -0,0 +1,488 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+
+<!-- $Id:$ -->
+
+<HTML>
+<HEAD>
+<TITLE>Using the TAO::Transport::Current Feature</TITLE>
+
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
+
+<LINK REL="STYLESHEET" HREF="transport_current.css">
+
+</HEAD>
+
+<BODY TEXT = "#000000" LINK="#000fff" VLINK="#ff0f0f" BGCOLOR="#ffffff">
+
+<P>
+
+<H1 ALIGN="CENTER">Using the TAO::Transport::Current Feature</H1>
+
+
+<P ALIGN="CENTER">
+Object Computing Inc.<BR>
+St.Louis, Missouri
+</P>
+
+<P ALIGN="CENTER">
+<SMALL><STRONG>
+<A HREF="mailto:iliyan@ociweb.com">Iliyan Jeliazkov</A>
+<A HREF="mailto:mesnier_p@ociweb.com">Phil Mesnier</A>
+ and <A HREF="mailto:<john_c@ociweb.com">Ciju John</A>
+</STRONG></SMALL>
+</P>
+
+<HR>
+
+<P>
+<H3>Scope and Context</H3><P>
+
+<P>In TAO, it is just too hard to obtain statistical or pretty much any operational information about the network transport which the ORB is using. While this is a direct corollary of the CORBA's design paradigm which mandates hiding all this hairy stuff behind non-transparent abstractions, it also precludes effective ORB and network monitoring.
+</P>
+
+<P>
+The Transport::Current feature intends to fill this gap by defining a
+framework for developing a wide range of solutions to this problem. It also provides a basic implementation for the most common case - the IIOP transport.
+</P>
+
+<P>
+By definition, transport-specific information is available in
+contexts where the ORB has selected a Transport:</P>
+
+<UL>
+ <LI>Within Client-side interception points;</LI>
+ <LI>Within Server-side interception points;</LI>
+ <LI>Inside a Servant up-call</LI>
+</UL>
+
+<P>
+The implementation is based on a generic service-oriented
+framework, implementing the TAO::Transport::Current interface. It is
+an optional service, which can be dynamically loaded. This service makes
+the Transport::Current interface available through
+orb->resolve_initial_references() . The basic idea is that whenever a Transport is
+chosen by the ORB, the Transport::Current (or a derivative) will have access
+to that instance and be able to provide some useful information.
+</P>
+
+<BR><HR>
+
+
+<P>
+<H3>
+Programmer's Reference
+</H3>
+
+<P>
+Consider the following IDL interface, describing a Factory for
+producing TAO::Transport::Traits instance, which represents
+transport-specific data.
+</P>
+
+<PRE>
+#include <IOP.pidl>
+#include <TimeBase.pidl>
+
+module TAO
+{
+ /// A type used to represent counters
+ typedef unsigned long long CounterT;
+
+ module Transport
+ {
+ /// Used to signal that a call was made within improper invocation
+ /// context. Also, this exception is thrown if no Transport has
+ /// been selected for the current thread, for example in a
+ /// collocated invocation.
+
+ exception NoContext
+ {
+ };
+
+ // The primary interface, providing access to Transport
+ // information, available to the current thread.
+
+ local interface Current
+ {
+ /// Transport ID, unique within the process.
+ readonly attribute long id raises (NoContext);
+
+ /// Bytes sent/received through the transport.
+ readonly attribute CounterT bytes_sent raises (NoContext);
+ readonly attribute CounterT bytes_received raises (NoContext);
+
+ /// Messages (requests and replies) sent/received using the current
+ /// protocol.
+ readonly attribute CounterT messages_sent raises (NoContext);
+ readonly attribute CounterT messages_received raises (NoContext);
+
+ /// The absolute time (miliseconds) since the transport has been
+ /// open.
+ readonly attribute TimeBase::TimeT open_since raises (NoContext);
+ };
+ };
+};
+</PRE>
+
+<P>
+As an example of a specialized Transport::Current is the Transport::IIOP::Current, which derives from Transport::Current and has an interface, described in the following IDL:
+</P>
+
+<PRE>
+#include "TC.idl"
+
+/// Provide a forward reference for the SSLIOP::Current
+module SSLIOP
+{
+ interface Current;
+};
+
+
+module TAO
+{
+ module Transport
+ {
+ module IIOP
+ {
+ // The primary interface, providing access to IIOP-specific
+ // transport information, if it is indeed an IIOP (-like) transport
+ // that has been selected.
+
+ local interface Current : TAO::Transport::Current
+ {
+ /// Remote host
+ readonly attribute string remote_host raises (NoContext);
+
+ /// Remote port Using long (signed) type to better accomodate
+ /// the Java mapping, which has no support for unsigned values
+ readonly attribute long remote_port raises (NoContext);
+
+ /// Local host
+ readonly attribute string local_host raises (NoContext);
+
+ /// Local port
+ readonly attribute long local_port raises (NoContext);
+
+ /// If this is a "secure" transport, this method will give you
+ /// the corresponding SSLIOP::Current
+ readonly attribute ::SSLIOP::Current ssliop_current raises (NoContext);
+ };
+ };
+ };
+};
+</PRE>
+
+
+<P>
+<H3>
+User's Guide
+</H3>
+
+<P>
+The TAO::Transport::Current can be used as a base interface for a more specialized TAO::Transport::X::Current. It is not required, however that a more specialized Current inherits from it.
+</P>
+
+<P>
+Typical, generic usage is shown in the
+$TAO_ROOT/orbsvcs/tests/Transport_Current/Framework test:
+</P>
+
+<PRE>
+...
+ // Get the Current object.
+ ::CORBA::Object_var tcobject =
+ orb->resolve_initial_references ("TAO::Transport::Current"
+ ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ ::TAO::Transport::Current_var tc =
+ ::TAO::Transport::Current::_narrow (tcobject.in ()
+ ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (tc.in ()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) client - ERROR: Could not resolve ")
+ ACE_TEXT ("TAO::Transport::Current object.\n")));
+
+ ACE_TRY_THROW (CORBA::INTERNAL ());
+ }
+...
+</PRE>
+
+<P>
+Another example is available from the $TAO_ROOT/orbsvcs/tests/Transport_Current/IIOP test. This fragment shows how to obtain transport-specific information:
+</P>
+
+<PRE>
+...
+ // Get the specific Current object.
+ CORBA::Object_var tcobject =
+ orb->resolve_initial_references (ACE_TEXT_ALWAYS_CHAR ("TAO::Transport::IIOP::Current")
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ Transport::IIOP::Current_var tc =
+ Transport::IIOP::Current::_narrow (tcobject.in ()
+ ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (tc.in ()))
+ ACE_TRY_THROW (CORBA::INTERNAL ());
+
+ ::CORBA::String_var rhost (tc->remote_host (ACE_ENV_SINGLE_ARG_PARAMETER));
+ ACE_TRY_CHECK;
+
+ ::CORBA::String_var lhost (tc->local_host (ACE_ENV_SINGLE_ARG_PARAMETER));
+ ACE_TRY_CHECK;
+
+ ::CORBA::Long id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT bs = tc->bytes_sent (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT br = tc->bytes_received (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT rs = tc->messages_sent (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT rr = tc->messages_received (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+...
+</PRE>
+
+
+
+<P>
+<H3>
+Configuration, Bootstrap, Initialization and Operation
+</H3>
+
+<P>
+To use the Transport Current features the framework must be loaded
+through the Service Configuration framework. For example, using
+something like this:
+</P>
+
+<PRE>
+dynamic TAO_Transport_Current_Loader Service_Object * libTAO_Transport_Current.so:_make_TAO_Transport_Current_Loader() ""
+</PRE>
+
+<P>
+The Transport_Current_Loader service uses an ORB initializer to register the "TAO::Transport::Current" name in a way that allows it to be resolved via orb->resolve_initial_references(). The implementation is the TAO::Transport::Current_Impl class.
+</P>
+
+<P>
+A transport-specific Traits_Factory objects are loaded like this:
+</P>
+
+<PRE>
+...
+dynamic TAO_Transport_IIOP_Current_Loader Service_Object * TAO_TC_IIOP:_make_TAO_Transport_IIOP_Current_Loader() ""
+...
+</PRE>
+
+<P>
+Note that any number of transport-specific Current interfaces may be available at any one time.
+</P>
+
+<P>
+Whenever a Transport::Current method is invoked, a pointer to the currently selected Transport instance must be accessible through Thread Specific Storage (TSS). For each thread, this is managed by modifying the TAO classes, instances of which are created on the stack during request/response processing.
+</P>
+
+<P>
+<H3>
+Implementation and Required Changes
+</H3>
+
+<P>
+The primary implementation is predicated upon usage of thread specific
+storage (TSS) and the guarantees C++ provides for calling the
+constructor and the destructor of automatic (stack-based)
+objects. Some existing objects, used in TAO will have to be modified
+and the necessary changes, both for client and the server side are
+detailed below.
+</P>
+
+<H4>
+Client Side: Sending Requests or Replies
+</H4>
+
+
+<P>
+The Profile_Transport_Resolver instance contains the reference to the
+Transport, which is the TAO implementation structure that is needed to extract
+any protocol-specific information. An
+instance of Profile_Transport_Resolver lives on the stack, starting
+inside a call to Invocation_Adapter::invoke_remote_i(), or
+LocateRequest_Invocation_Adapter::invoke(). In the case of collocated
+invocations no such object is created.
+</P>
+
+<P>
+It is then passed around the calls that follow, except for the calls
+to the following Invocation_Base methods: send_request_interception(),
+receive_other_interception(), receive_reply_interception(),
+handle_any_exception(), handle_all_exception();
+</P>
+
+<P>
+Note that these in turn call the client-side interception points and
+that is where information about the transport will be needed. In order
+to make the transport information accessible inside those methods, we
+changed Profile_Transport_Resolver and the TAO_ServerRequest classes to
+ incorporate an additional member:
+</P>
+
+<PRE>
+...
+TAO::Transport_Selection_Guard transport_;
+...
+</PRE>
+
+
+<P>
+This guard automatically keeps track of the currenty selected Transport from within its constructor and destructor. The rest of the TC framework makes sure this pointer is stored in a thread-specific storage, by adding an additional member to TSS_Resources:
+</P>
+
+<PRE>
+...
+TAO::Transport_Selection_Guard* tsg_;
+...
+</PRE>
+
+<P>
+The idea is to keep a pointer to the last guard on the current thread. Each guard keeps a pointer to the previous, effectively creating a stack of transport selection guards. The stack structure ensures both that the selection/deselection of a Transport will be correctly handled. It also ensures that, in case the current thread temporarily changes the Transport, the previous “current” transport will be preserved, no matter how many times such change occurs. A good example for this is a nested up-call scenario.
+</P>
+
+<P>
+Inside an interceptor, one can use the methods from Transport Current to obtain information on the currently selected transport. The implementation simply looks up the TAO_Transport pointer via TSS_Resources::tsg_ and obtains the requested data.
+</P>
+
+
+
+<H4>
+Server Side: Request Processing
+</H4>
+
+
+<P>
+On the server side, the TAO_ServerRequest instance already has a
+Transport pointer. The TAO_ServerRequest lives on the stack, starting
+its life inside a call to TAO_GIOP_Message_Base::process_request().
+</P>
+
+<P>
+Similarly to the client-side, we changed the TAO_ServerRequest
+to add a field:
+</P>
+
+<PRE>
+...
+TAO::Transport_Selection_Guard transport_;
+...
+</PRE>
+
+<P>
+Operation is similar to the client-side case. In the collocated case there may not be a
+transport available, so the TSS slot will be null.
+</P>
+
+<P>
+Inside an interceptor then, one can use an RIR-resolved
+TransportCurrent to create a specialization of TransportInfo, based on
+the kind of Transport used. Then they would _downcast() it to the
+specific type.
+</P>
+
+<H3>
+Structural and Footprint Impact
+</H3>
+
+<P>
+As the IIOP implementation of the Transport Current functionality requires additional
+data to be kept about the Transport, we added a new field to TAO_Transport:
+</P>
+
+<PRE>
+...
+ /// Transport statistics
+ TAO::Transport::Stats* stats_
+...
+</PRE>
+
+<P>
+TAO::Transport::Stats is a simple structure, which keeps track of useful statistical
+information about how a transport is used:
+</P>
+
+<PRE>
+...
+ class TAO_Export Stats
+ {
+ public:
+ Stats ();
+
+ void messages_sent (size_t message_length);
+ CORBA::LongLong messages_sent (void) const;
+ CORBA::LongLong bytes_sent (void) const;
+
+ void messages_received (size_t message_length);
+ CORBA::LongLong messages_received (void) const;
+ CORBA::LongLong bytes_received (void) const;
+
+ void opened_since (const ACE_Time_Value& tv);
+ const ACE_Time_Value& opened_since (void) const;
+
+ private:
+ CORBA::LongLong messages_rcvd_; // 32bits not enough (?)
+ CORBA::LongLong messages_sent_; // 32bits not enough (?)
+
+ ACE_Basic_Stats bytes_rcvd_;
+ ACE_Basic_Stats bytes_sent_;
+
+ ACE_Time_Value opened_since_;
+ };
+...
+</PRE>
+
+<P>
+To gather the statistics the TAO_Transport::send_message_shared() and TAO_Transport::process_parsed_messages() must be modified. These are non-virtual methods and are being called as part of request and reply processing regardless of what the most derived Transport type is. This property ensures that any specific Transport will have access to these statistics.
+</P>
+
+<H3>
+Performance Impact
+</H3>
+
+<P>
+As the implementation of the Transport Current functionality
+necessitates some additional processing on the critical path of an
+invocation, we are expecting a performance impact when the
+functionality is being used.
+</P>
+
+<P>
+It is possible at build time, to
+disable the functionality, so that applications only incur the penalty
+if they require it. The ORB, by default will not support the Transport Current functionality.
+Use the following #define (in your config.h file) to enable it:
+</P>
+
+<PRE>
+#define TAO_HAS_TRANSPORT_CURRENT 1
+</PRE>
+
+<H3>
+Example Code
+</H3>
+
+<P>
+Look at $TAO_ROOT/orbsvcs/tests/Transport_Current for code which illustrates and tests this feature.
+</P>
+</BODY>
+</HTML>
diff --git a/TAO/docs/transport_current/transport_current.css b/TAO/docs/transport_current/transport_current.css
new file mode 100644
index 00000000000..1993b851311
--- /dev/null
+++ b/TAO/docs/transport_current/transport_current.css
@@ -0,0 +1,31 @@
+
+/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */
+.MATH { font-family: "Century Schoolbook", serif; }
+.MATH I { font-family: "Century Schoolbook", serif; font-shape: italic }
+.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold }
+
+/* implement both fixed-size and relative sizes */
+SMALL.XTINY { font-size : xx-small }
+SMALL.TINY { font-size : x-small }
+SMALL.SCRIPTSIZE { font-size : smaller }
+SMALL.FOOTNOTESIZE { font-size : small }
+SMALL.SMALL { }
+BIG.LARGE { }
+BIG.XLARGE { font-size : large }
+BIG.XXLARGE { font-size : x-large }
+BIG.HUGE { font-size : larger }
+BIG.XHUGE { font-size : xx-large }
+
+/* heading styles */
+H1 { }
+H2 { }
+H3 { }
+H4 { }
+H5 { }
+
+/* mathematics styles */
+DIV.displaymath { } /* math displays */
+TD.eqno { } /* equation-number cells */
+
+
+/* document-specific styles come next */
diff --git a/TAO/tao/ORB_Core.h b/TAO/tao/ORB_Core.h
index 8bf85dcd2f7..15967c95d49 100644
--- a/TAO/tao/ORB_Core.h
+++ b/TAO/tao/ORB_Core.h
@@ -1409,9 +1409,6 @@ public:
private:
- /// The singleton instance.
-// static TAO_ORB_Core_Static_Resources* instance_;
-
/// Mostly unused variable whose sole purpose is to enforce
/// the instantiation of a TAO_ORB_Core_Static_Resources instance
/// at initialization time.
diff --git a/TAO/tao/Profile_Transport_Resolver.cpp b/TAO/tao/Profile_Transport_Resolver.cpp
index c8f6a31b4d5..f3beae91869 100644
--- a/TAO/tao/Profile_Transport_Resolver.cpp
+++ b/TAO/tao/Profile_Transport_Resolver.cpp
@@ -39,7 +39,7 @@ namespace TAO
this->profile_->_decr_refcnt ();
}
- if (this->transport_)
+ if (this->transport_.get ())
{
if (this->is_released_ == false)
{
@@ -93,7 +93,7 @@ namespace TAO
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
- if (this->transport_ == 0)
+ if (this->transport_.get () == 0)
{
ACE_THROW (CORBA::INTERNAL ());
}
@@ -187,20 +187,20 @@ namespace TAO
ACE_ASSERT(con != 0);
if (parallel)
{
- this->transport_ = con->parallel_connect (this, desc, timeout
- ACE_ENV_ARG_PARAMETER);
+ this->transport_.set (con->parallel_connect (this, desc, timeout
+ ACE_ENV_ARG_PARAMETER));
}
else
{
- this->transport_ = con->connect (this, desc, timeout
- ACE_ENV_ARG_PARAMETER);
+ this->transport_.set (con->connect (this, desc, timeout
+ ACE_ENV_ARG_PARAMETER));
}
ACE_CHECK_RETURN (false);
// A timeout error occurred.
// If the user has set a roundtrip timeout policy, throw a timeout
// exception. Otherwise, just fall through and return false to
// look at the next endpoint.
- if (this->transport_ == 0 &&
+ if (this->transport_.get () == 0 &&
has_con_timeout == false &&
errno == ETIME)
{
@@ -211,7 +211,7 @@ namespace TAO
CORBA::COMPLETED_NO),
false);
}
- else if (this->transport_ == 0)
+ else if (this->transport_.get () == 0)
{
return false;
}
@@ -272,7 +272,12 @@ namespace TAO
// the cache increments the reference count on the transport if the
// find is successful. Find_transport uses negative logic in its return,
// 0 for success
- return (cache.find_transport(desc,this->transport_) == 0);
+ TAO_Transport* tmp = this->transport_.get ();
+ if (cache.find_transport(desc, tmp) != 0)
+ return -1;
+
+ this->transport_.set (tmp);
+ return 0;
}
diff --git a/TAO/tao/Profile_Transport_Resolver.h b/TAO/tao/Profile_Transport_Resolver.h
index 34cef016395..2816f63dc2c 100644
--- a/TAO/tao/Profile_Transport_Resolver.h
+++ b/TAO/tao/Profile_Transport_Resolver.h
@@ -24,6 +24,7 @@
#include "ace/CORBA_macros.h"
#include "tao/SystemException.h"
+#include "tao/Transport_Selection_Guard.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
class ACE_Time_Value;
@@ -178,7 +179,10 @@ namespace TAO
TAO_Stub *stub_;
/// The transport selected for this invocation.
- TAO_Transport *transport_;
+
+ /// Using the wrapper guard ensures it is available for use with
+ /// the Transport Current interfaces.
+ TAO::Transport_Selection_Guard transport_;
/// The profile that has been selected for this invocation.
TAO_Profile *profile_;
diff --git a/TAO/tao/Profile_Transport_Resolver.inl b/TAO/tao/Profile_Transport_Resolver.inl
index 3617d71e3da..07e89301fa5 100644
--- a/TAO/tao/Profile_Transport_Resolver.inl
+++ b/TAO/tao/Profile_Transport_Resolver.inl
@@ -43,7 +43,7 @@ namespace TAO
ACE_INLINE TAO_Transport *
Profile_Transport_Resolver::transport (void) const
{
- return this->transport_;
+ return this->transport_.get ();
}
ACE_INLINE bool
diff --git a/TAO/tao/TAO_Server_Request.cpp b/TAO/tao/TAO_Server_Request.cpp
index 5a2cebeee48..18666d56946 100644
--- a/TAO/tao/TAO_Server_Request.cpp
+++ b/TAO/tao/TAO_Server_Request.cpp
@@ -82,6 +82,7 @@ TAO_ServerRequest::TAO_ServerRequest (TAO_Pluggable_Messaging *mesg_base,
, caught_exception_ (0)
, reply_status_ (-1)
#endif /* TAO_HAS_INTERCEPTORS == 1 */
+ , transport_selection_guard_ (transport)
{
ACE_FUNCTION_TIMEPROBE (TAO_SERVER_REQUEST_START);
// No-op.
@@ -126,6 +127,7 @@ TAO_ServerRequest::TAO_ServerRequest (TAO_Pluggable_Messaging *mesg_base,
, caught_exception_ (0)
, reply_status_ (-1)
#endif /* TAO_HAS_INTERCEPTORS == 1 */
+ , transport_selection_guard_ (transport)
{
this->profile_.object_key (object_key);
parse_error = 0;
@@ -163,6 +165,7 @@ TAO_ServerRequest::TAO_ServerRequest (TAO_ORB_Core * orb_core,
, caught_exception_ (0)
, reply_status_ (-1)
#endif /* TAO_HAS_INTERCEPTORS == 1 */
+ , transport_selection_guard_ (0)
{
// Have to use a const_cast<>. *sigh*
this->profile_.object_key (
diff --git a/TAO/tao/TAO_Server_Request.h b/TAO/tao/TAO_Server_Request.h
index 7cd383f5dd5..8034d920b28 100644
--- a/TAO/tao/TAO_Server_Request.h
+++ b/TAO/tao/TAO_Server_Request.h
@@ -29,6 +29,7 @@
#include "tao/Tagged_Profile.h"
#include "tao/Service_Context.h"
#include "tao/Object.h"
+#include "tao/Transport_Selection_Guard.h"
#if TAO_HAS_INTERCEPTORS == 1
@@ -375,6 +376,10 @@ private:
/// Reply status for the current request.
PortableInterceptor::ReplyStatus reply_status_;
#endif /* TAO_HAS_INTERCEPTORS == 1 */
+
+ /// An RAII (resource acquisition is initialization) class instance
+ /// for interfacing with TSS storage for the "current" transport.
+ TAO::Transport_Selection_Guard transport_selection_guard_;
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/TAO_Server_Request.inl b/TAO/tao/TAO_Server_Request.inl
index 48bc3d00d82..45c05553533 100644
--- a/TAO/tao/TAO_Server_Request.inl
+++ b/TAO/tao/TAO_Server_Request.inl
@@ -35,6 +35,7 @@ TAO_ServerRequest::TAO_ServerRequest (void)
, caught_exception_ (0)
, reply_status_ (-1)
#endif /* TAO_HAS_INTERCEPTORS == 1 */
+ , transport_selection_guard_ (0)
{
}
diff --git a/TAO/tao/TSS_Resources.cpp b/TAO/tao/TSS_Resources.cpp
index 73ec7175070..55bcde08649 100644
--- a/TAO/tao/TSS_Resources.cpp
+++ b/TAO/tao/TSS_Resources.cpp
@@ -23,7 +23,9 @@ TAO_TSS_Resources::TAO_TSS_Resources (void)
#endif /* TAO_HAS_CORBA_MESSAGING == 1 */
, gui_resource_factory_ (0)
-
+#if (TAO_HAS_TRANSPORT_CURRENT == 1)
+ , tsg_ (0)
+#endif /* TAO_HAS_TRANSPORT_CURRENT */
{
}
diff --git a/TAO/tao/TSS_Resources.h b/TAO/tao/TSS_Resources.h
index 0891f1e43da..3212040ead3 100644
--- a/TAO/tao/TSS_Resources.h
+++ b/TAO/tao/TSS_Resources.h
@@ -33,6 +33,7 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL
namespace TAO
{
class GUIResource_Factory;
+ class Transport_Selection_Guard;
}
/**
* @class TAO_TSS_Resources
@@ -105,6 +106,17 @@ public:
* are operational only in within the context of GUI event loops.
*/
TAO::GUIResource_Factory * gui_resource_factory_;
+
+#if TAO_HAS_TRANSPORT_CURRENT == 1
+
+ /// A TSS for a pointer to the current transport guard (see
+ /// below). The guard keeps track of the Transport, if any that has
+ /// been selected for use by the current thread, in the context of
+ /// an upcall or client-side interceptor.
+
+ TAO::Transport_Selection_Guard* tsg_;
+
+#endif /* TAO_HAS_TRANSPORT_CURRENT == 1 */
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Transport.cpp b/TAO/tao/Transport.cpp
index 82bf0f3cdab..83f2a3f114d 100644
--- a/TAO/tao/Transport.cpp
+++ b/TAO/tao/Transport.cpp
@@ -160,6 +160,13 @@ TAO_Transport::TAO_Transport (CORBA::ULong tag,
// Create TMS now.
this->tms_ = cf->create_transport_mux_strategy (this);
+#if TAO_HAS_TRANSPORT_CURRENT == 1
+ // Allocate stats
+ ACE_NEW_THROW_EX (this->stats_,
+ TAO::Transport::Stats,
+ CORBA::NO_MEMORY ());
+#endif /* TAO_HAS_TRANSPORT_CURRENT == 1 */
+
/*
* Hook to add code that initializes components that
* belong to the concrete protocol implementation.
@@ -1209,21 +1216,33 @@ TAO_Transport::send_message_shared_i (TAO_Stub *stub,
const ACE_Message_Block *message_block,
ACE_Time_Value *max_wait_time)
{
+ int ret = 0;
+ size_t message_length = message_block->length ();
+
switch (message_semantics)
{
case TAO_Transport::TAO_TWOWAY_REQUEST:
- return this->send_synchronous_message_i (message_block,
- max_wait_time);
+ ret = this->send_synchronous_message_i (message_block,
+ max_wait_time);
+ break;
+
case TAO_Transport::TAO_REPLY:
- return this->send_reply_message_i (message_block,
- max_wait_time);
+ ret = this->send_reply_message_i (message_block,
+ max_wait_time);
+ break;
+
case TAO_Transport::TAO_ONEWAY_REQUEST:
- return this->send_asynchronous_message_i (stub,
- message_block,
- max_wait_time);
+ ret = this->send_asynchronous_message_i (stub,
+ message_block,
+ max_wait_time);
+ break;
}
- return -1;
+ // "Count" the message, only if no error was encountered.
+ if (ret != -1 && this->stats_ != 0)
+ this->stats_->messages_sent (message_length);
+
+ return ret;
}
int
@@ -2193,7 +2212,9 @@ TAO_Transport::process_parsed_messages (TAO_Queued_Data *qd,
// Get the <message_type> that we have received
const TAO_Pluggable_Message_Type t = qd->msg_type_;
- // int result = 0;
+ // Update stats, if any
+ if (this->stats_ != 0)
+ this->stats_->messages_received (qd->msg_block_->length ());
if (t == TAO_PLUGGABLE_MESSAGE_CLOSECONNECTION)
{
diff --git a/TAO/tao/Transport.h b/TAO/tao/Transport.h
index 1f2efb4ddd7..ad9a8a25155 100644
--- a/TAO/tao/Transport.h
+++ b/TAO/tao/Transport.h
@@ -28,6 +28,7 @@
#include "tao/Incoming_Message_Queue.h"
#include "tao/Incoming_Message_Stack.h"
#include "ace/Time_Value.h"
+#include "ace/Basic_Stats.h"
struct iovec;
@@ -60,6 +61,13 @@ namespace TAO
TAO_SERVER_ROLE = 1,
TAO_CLIENT_ROLE = 2
};
+
+ namespace Transport
+ {
+ /// Transport-level statistics. Initially introduced to support
+ /// the "Transport Current" functionality.
+ class Stats;
+ }
}
/*
@@ -770,6 +778,9 @@ public:
/// connection is closed.
void send_connection_closed_notifications (void);
+ /// Transport statistics
+ TAO::Transport::Stats* stats (void) const;
+
private:
/// Helper method that returns the Transport Cache Manager.
@@ -1065,6 +1076,9 @@ private:
TAO_MMAP_Allocator * const mmap_allocator_;
#endif /* TAO_HAS_SENDFILE==1 */
+ /// Statistics
+ TAO::Transport::Stats* stats_;
+
/*
* specialization hook to add class members from concrete
* transport class onto the base transport class. Please
@@ -1080,6 +1094,61 @@ private:
//@@ TAO_TRANSPORT_SPL_EXTERN_ADD_HOOK
+namespace TAO
+{
+ namespace Transport
+ {
+ /*
+ * @class Stats
+ *
+ * @brief Used to collect stats on a transport.
+ *
+ * The base class in (potentialy) extensible hierarchy used to
+ * specialize the information available for a specific protocol.
+ *
+ * This class is necessary for the implementation of the Transport
+ * Current feature.
+ *
+ * <B>See Also:</B>
+ *
+ * https://svn.dre.vanderbilt.edu/viewvc/Middleware/trunk/TAO/docs/transport_current/index.html?revision=HEAD
+ *
+ */
+ class TAO_Export Stats
+ {
+ public:
+ Stats ();
+
+ void messages_sent (size_t message_length);
+ CORBA::LongLong messages_sent (void) const;
+ CORBA::LongLong bytes_sent (void) const;
+
+ void messages_received (size_t message_length);
+ CORBA::LongLong messages_received (void) const;
+ CORBA::LongLong bytes_received (void) const;
+
+ void opened_since (const ACE_Time_Value& tv);
+ const ACE_Time_Value& opened_since (void) const;
+
+ private:
+ // @NOTE: I could have used bytes_rcvd_.samples_count() instead,
+ // however there was a suspicion that 32 bits would be
+ // insufficient.
+ CORBA::LongLong messages_rcvd_;
+
+ // @NOTE: I could have used bytes_sent_.samples_count() instead,
+ // however there was a suspicion that 32 bits would be
+ // insufficient.
+ CORBA::LongLong messages_sent_;
+
+ ACE_Basic_Stats bytes_rcvd_;
+ ACE_Basic_Stats bytes_sent_;
+
+ ACE_Time_Value opened_since_;
+ };
+ }
+}
+
TAO_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
diff --git a/TAO/tao/Transport.inl b/TAO/tao/Transport.inl
index ef9faafb1ac..e53d2848830 100644
--- a/TAO/tao/Transport.inl
+++ b/TAO/tao/Transport.inl
@@ -189,4 +189,71 @@ TAO_Transport::sent_byte_count (void) const
return this->sent_byte_count_;
}
+ACE_INLINE TAO::Transport::Stats*
+TAO_Transport::stats (void) const
+{
+ return this->stats_;
+}
+
+ACE_INLINE
+TAO::Transport::Stats::Stats ()
+ : messages_rcvd_ (0)
+ , messages_sent_ (0)
+ , bytes_rcvd_()
+ , bytes_sent_ ()
+ , opened_since_ ()
+{
+}
+
+ACE_INLINE void
+TAO::Transport::Stats::messages_sent (size_t message_length)
+{
+ this->messages_sent_++;
+ this->bytes_sent_.sample (message_length);
+}
+
+ACE_INLINE CORBA::LongLong
+TAO::Transport::Stats::messages_sent (void) const
+{
+ return this->messages_sent_;
+}
+
+ACE_INLINE CORBA::LongLong
+TAO::Transport::Stats::bytes_sent (void) const
+{
+ return this->bytes_sent_.sum_;
+}
+
+ACE_INLINE void
+TAO::Transport::Stats::messages_received (size_t message_length)
+{
+ this->messages_rcvd_++;
+ this->bytes_rcvd_.sample (message_length);
+}
+
+ACE_INLINE CORBA::LongLong
+TAO::Transport::Stats::messages_received (void) const
+{
+ return this->messages_rcvd_;
+}
+
+ACE_INLINE CORBA::LongLong
+TAO::Transport::Stats::bytes_received (void) const
+{
+ return this->bytes_rcvd_.sum_;
+}
+
+ACE_INLINE void
+TAO::Transport::Stats::opened_since (const ACE_Time_Value& tv)
+{
+ this->opened_since_ = tv;
+}
+
+ACE_INLINE const ACE_Time_Value&
+TAO::Transport::Stats::opened_since (void) const
+{
+ return this->opened_since_;
+}
+
+
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/TransportCurrent/Current_Impl.cpp b/TAO/tao/TransportCurrent/Current_Impl.cpp
new file mode 100644
index 00000000000..1965dd5bea2
--- /dev/null
+++ b/TAO/tao/TransportCurrent/Current_Impl.cpp
@@ -0,0 +1,106 @@
+// $Id:$
+
+#include "tao/Transport.h"
+#include "tao/Transport_Selection_Guard.h"
+
+#include "tao/TransportCurrent/Current_Loader.h"
+#include "tao/TransportCurrent/Current_Impl.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ namespace Transport
+ {
+
+ /// ctor
+ Current_Impl::Current_Impl (TAO_ORB_Core* core, size_t tss_slot_id)
+ : core_ (core)
+ , tss_slot_id_ (tss_slot_id)
+ {
+ }
+
+ /// dtor
+ Current_Impl::~Current_Impl (void)
+ {
+ }
+
+ /// Obtains the current transport. Throws a NoContext exception
+ /// if, there was no "current" transport selected on the current
+ /// thread.
+ const TAO_Transport*
+ Current_Impl::transport (ACE_ENV_SINGLE_ARG_DECL) const
+ ACE_THROW_SPEC ((NoContext))
+ {
+ Transport_Selection_Guard* topguard =
+ Transport_Selection_Guard::current (this->core_, this->tss_slot_id_);
+
+ if (topguard == 0)
+ ACE_THROW (NoContext());
+ ACE_CHECK;
+
+ return topguard->get ();
+ }
+
+ /// Obtains the current transport's stats
+ const TAO::Transport::Stats*
+ Current_Impl::transport_stats (ACE_ENV_SINGLE_ARG_DECL) const
+ ACE_THROW_SPEC ((NoContext))
+ {
+ static const TAO::Transport::Stats dummy;
+
+ const TAO_Transport* t =
+ this->transport (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ return (t==0 || t->stats () == 0) ? &dummy : t->stats ();
+ }
+
+ CORBA::Long Current_Impl::id (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ const TAO_Transport* t =
+ this->transport (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ return (t==0) ? 0 : t->id ();
+ }
+
+ CounterT Current_Impl::bytes_sent (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ return transport_stats ()->bytes_sent ();
+ }
+
+ CounterT Current_Impl::bytes_received (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ return transport_stats ()->bytes_received ();
+ }
+
+ CounterT Current_Impl::messages_sent (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ return transport_stats ()->messages_sent ();
+ }
+
+ CounterT Current_Impl::messages_received (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ return transport_stats ()->messages_received ();
+ }
+
+ TimeBase::TimeT Current_Impl::open_since (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ TimeBase::TimeT msecs = 0;
+ transport_stats ()->opened_since ().msec (msecs);
+ return msecs;
+ }
+
+ };
+
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
diff --git a/TAO/tao/TransportCurrent/Current_Impl.h b/TAO/tao/TransportCurrent/Current_Impl.h
new file mode 100644
index 00000000000..02e7df88e11
--- /dev/null
+++ b/TAO/tao/TransportCurrent/Current_Impl.h
@@ -0,0 +1,123 @@
+// $Id$
+
+#ifndef CURRENT_IMPL_H
+#define CURRENT_IMPL_H
+
+#include /**/ "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/TransportCurrent/TCC.h"
+#include "tao/LocalObject.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_Transport;
+
+namespace TAO
+{
+ namespace Transport
+ {
+
+ // Forward decl
+ class Stats;
+
+ /**
+ * @class Current_impl
+ *
+ * @brief Implementation of the TAO::Transport::Current
+ * interface.
+ *
+ * Current_Impl is useful for obtaining information about the
+ * Transport, associated with the calling thread.
+ */
+ class TAO_Transport_Current_Export Current_Impl
+ : public virtual Current
+ , public virtual TAO_Local_RefCounted_Object
+ {
+ public:
+
+ /// Constructor.
+ Current_Impl (TAO_ORB_Core* core, size_t tss_slot_id);
+
+ /**
+ * These are methods exposed by the
+ * PortableInterceptor::Current interface.
+ */
+ //@{
+ virtual CORBA::Long id (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+
+ virtual CounterT bytes_sent (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+
+ virtual CounterT bytes_received (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+
+ virtual CounterT messages_sent (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+
+ virtual CounterT messages_received (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+
+ virtual ::TimeBase::TimeT open_since (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+ //@}
+
+ protected:
+
+ /**
+ * Some helper methods
+ */
+ //@{
+ /// A (strategy) method used to obtain the transport ptr
+ const TAO_Transport* transport (ACE_ENV_SINGLE_ARG_DECL) const
+ ACE_THROW_SPEC ((NoContext));
+
+ /// A Stats instance. If protocol is unavailable (0) or the
+ /// TAO_HAS_TRANSPORT_CURRENT macro is defined as anything but
+ /// 1, a single static instance will be used.
+ const TAO::Transport::Stats* transport_stats (ACE_ENV_SINGLE_ARG_DECL) const
+ ACE_THROW_SPEC ((NoContext));
+ //@}
+
+ /// Destructor is protected to enforce the fact this class is
+ /// reference counted, and should not be destroyed using
+ /// delete() by anything other than the reference counting
+ /// mechanism.
+ virtual ~Current_Impl (void);
+
+ private:
+
+ /// Prevent copying through the copy constructor and the
+ /// assignment operator.
+ //@{
+ Current_Impl (const Current_Impl &);
+ void operator= (const Current_Impl &);
+ //@}
+
+ private:
+
+ // The ORB (core) that owes us.
+ TAO_ORB_Core* core_;
+
+ // The ORB's TSS slot id for the Transport ptr
+ size_t tss_slot_id_;
+
+ };
+
+ };
+
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+/* #if defined (__ACE_INLINE__) */
+/* # include "Current_Impl.inl" */
+/* #endif /\* __ACE_INLINE__ *\/ */
+
+#include /**/ "ace/post.h"
+
+#endif /* CURRENT_IMPL_H */
diff --git a/TAO/tao/TransportCurrent/Current_Loader.cpp b/TAO/tao/TransportCurrent/Current_Loader.cpp
new file mode 100644
index 00000000000..04210f9ba21
--- /dev/null
+++ b/TAO/tao/TransportCurrent/Current_Loader.cpp
@@ -0,0 +1,155 @@
+/* -*- C++ -*- */
+
+// =================================================================
+/**
+ * @file Current_Loader.cpp
+ *
+ * $Id$
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ *
+ */
+// =================================================================
+
+
+#include "ace/Service_Config.h"
+
+#include "tao/ORB_Constants.h"
+#include "tao/ORBInitializer_Registry.h"
+
+#include "tao/PI/PI.h"
+
+#include "tao/TransportCurrent/Current_ORBInitializer.h"
+#include "tao/TransportCurrent/Current_Loader.h"
+#include "tao/TransportCurrent/Current_Impl.h"
+
+ACE_RCSID (Transport_Current,
+ Current_Loader,
+ "$Id$")
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ namespace Transport
+ {
+
+ /// A helper method for obtaining access to the the Transport
+ /// Factory Manager instance.
+
+ Current_Loader*
+ Current_Loader::instance (void)
+ {
+ Current_Loader *cl =
+ ACE_Dynamic_Service <Current_Loader>::instance (ACE_TEXT ("TAO_Transport_Current_Loader"));
+
+ if (cl == 0)
+#if defined (TAO_AS_STATIC_LIBS)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Unable to obtain Current::Loader instance: %m\n")),
+ 0);
+ return 0;
+ }
+#else
+ {
+ // In case we build shared, try to load the appropriate library.
+ ACE_Service_Config::process_directive
+ (ACE_DYNAMIC_SERVICE_DIRECTIVE("TAO_Transport_Current_Loader",
+ "TAO_TC",
+ "_make_TAO_Transport_Current_Loader",
+ ""));
+ cl = ACE_Dynamic_Service<Current_Loader>::instance (ACE_TEXT ("TAO_Transport_Current_Loader"));
+ }
+#endif /* TAO_AS_STATIC_LIBS */
+
+ if (cl != 0)
+ return cl;
+
+ if (TAO_debug_level > 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Unable to obtain Current::Loader instance: %m\n")),
+ 0);
+ return 0;
+ }
+
+
+ /// dtor
+
+ Current_Loader::~Current_Loader (void)
+ {
+ }
+
+
+
+ /// Initializes object when dynamic linking occurs.
+
+ int
+ Current_Loader::init (int, ACE_TCHAR *[])
+ {
+ PortableInterceptor::ORBInitializer_ptr tmp = 0;
+ ACE_NEW_THROW_EX (tmp,
+ Current_ORBInitializer<Current_Impl>
+ (ACE_TEXT ("TAO::Transport::Current")),
+ CORBA::NO_MEMORY
+ (CORBA::SystemException::_tao_minor_code (TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+ ACE_TRY_CHECK;
+
+ PortableInterceptor::ORBInitializer_var initializer (tmp);
+
+ PortableInterceptor::register_orb_initializer (initializer.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ return 0;
+ }
+
+ } /* namespace Transport */
+
+} /* namespace TAO */
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+
+
+
+
+#if defined (TAO_AS_STATIC_LIBS)
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_STATIC_SVC_REQUIRE (TAO_Transport_Current_Loader);
+
+namespace TAO
+{
+ namespace Transport
+ {
+ int current_static_initializer (void)
+ {
+ ACE_STATIC_SVC_REGISTER (TAO_Transport_Current_Loader);
+ return 0;
+ }
+
+ }
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* defined (TAO_AS_STATIC_LIBS) */
+
+
+
+
+ACE_STATIC_SVC_DEFINE (TAO_Transport_Current_Loader,
+ ACE_TEXT ("TAO_Transport_Current_Loader"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_Transport_Current_Loader),
+ ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+ACE_FACTORY_NAMESPACE_DEFINE (TAO_Transport_Current,
+ TAO_Transport_Current_Loader,
+ TAO::Transport::Current_Loader)
diff --git a/TAO/tao/TransportCurrent/Current_Loader.h b/TAO/tao/TransportCurrent/Current_Loader.h
new file mode 100644
index 00000000000..bab40b4f003
--- /dev/null
+++ b/TAO/tao/TransportCurrent/Current_Loader.h
@@ -0,0 +1,91 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Current_Loader.h
+ *
+ * $Id$
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef TAO_TRANSPORT_CURRENT_LOADER_H
+#define TAO_TRANSPORT_CURRENT_LOADER_H
+
+#include /**/ "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Service_Object.h"
+#include "tao/Versioned_Namespace.h"
+#include "tao/TransportCurrent/Transport_Current_Export.h"
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ class ORBInitializer_Registry_Adapter;
+
+ namespace Transport
+ {
+
+ class TAO_Transport_Current_Export Current_Loader
+ : public ACE_Service_Object
+ {
+ public:
+
+ /// A helper method for obtaining access to the the Transport
+ /// Factory Manager instance.
+ static Current_Loader* instance (void);
+
+ public:
+
+ /// Initializes object when dynamic linking occurs.
+ virtual int init (int argc, ACE_TCHAR *argv[]);
+
+ protected:
+
+ // Protected destructor to enforce reference counting discipline
+ virtual ~Current_Loader (void);
+
+ ORBInitializer_Registry_Adapter* orbinitializer_registry (void);
+
+ private:
+
+ /// A cache for the registry pointer
+ ORBInitializer_Registry_Adapter* oir_;
+ };
+
+ };
+};
+
+
+#if defined (TAO_AS_STATIC_LIBS)
+namespace TAO
+{
+ namespace Transport
+ {
+ int current_static_initializer (void);
+ };
+};
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* defined (TAO_AS_STATIC_LIBS) */
+
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Transport_Current,
+ TAO_Transport_Current_Loader)
+
+ACE_FACTORY_DECLARE (TAO_Transport_Current,
+ TAO_Transport_Current_Loader)
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_TRANSPORT_CURRENT_LOADER_H */
diff --git a/TAO/tao/TransportCurrent/Current_ORBInitializer.cpp b/TAO/tao/TransportCurrent/Current_ORBInitializer.cpp
new file mode 100644
index 00000000000..63c0b0e7c01
--- /dev/null
+++ b/TAO/tao/TransportCurrent/Current_ORBInitializer.cpp
@@ -0,0 +1,51 @@
+// $Id:$
+
+#ifndef CURRENT_ORBINITIALIZER_CPP
+#define CURRENT_ORBINITIALIZER_CPP
+
+#include "tao/ORB_Constants.h"
+#include "tao/TransportCurrent/Current_ORBInitializer.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ namespace Transport
+ {
+
+ template <typename Impl>
+ Current_ORBInitializer<Impl>::Current_ORBInitializer(const ACE_TCHAR* id)
+ : Current_ORBInitializer_Base (id)
+ {
+ }
+
+
+ template <typename Impl>
+ TAO::Transport::Current_ptr
+ Current_ORBInitializer<Impl>::make_current_instance (TAO_ORB_Core* core,
+ size_t tss_slot_id
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ // Create the Current
+ Current_ptr tmp = 0;
+ ACE_NEW_THROW_EX (tmp,
+ Impl (core, tss_slot_id),
+ CORBA::NO_MEMORY
+ (CORBA::SystemException::_tao_minor_code (TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+ ACE_CHECK;
+
+ return tmp;
+ }
+
+ }
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* CURRENT_ORBINITIALIZER_CPP */
diff --git a/TAO/tao/TransportCurrent/Current_ORBInitializer.h b/TAO/tao/TransportCurrent/Current_ORBInitializer.h
new file mode 100644
index 00000000000..8d477c76f46
--- /dev/null
+++ b/TAO/tao/TransportCurrent/Current_ORBInitializer.h
@@ -0,0 +1,65 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Current_ORBInitializer.h
+ *
+ * $Id$
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef CURRENT_ORBINITIALIZER_H
+#define CURRENT_ORBINITIALIZER_H
+
+#include /**/ "ace/pre.h"
+
+#include "tao/TransportCurrent/Current_ORBInitializer_Base.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ namespace Transport
+ {
+
+ template <typename Impl>
+ class TAO_Transport_Current_Export Current_ORBInitializer
+ //class Current_ORBInitializer
+ : public Current_ORBInitializer_Base
+ {
+ public:
+ Current_ORBInitializer (const ACE_TCHAR* id);
+
+
+ protected:
+ virtual TAO::Transport::Current_ptr
+ make_current_instance (TAO_ORB_Core* c,
+ size_t s
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ };
+
+ };
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "tao/TransportCurrent/Current_ORBInitializer.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("tao/TransportCurrent/Current_ORBInitializer.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+
+#include /**/ "ace/post.h"
+
+#endif /* CURRENT_ORBINITIALIZER_H */
diff --git a/TAO/tao/TransportCurrent/Current_ORBInitializer_Base.cpp b/TAO/tao/TransportCurrent/Current_ORBInitializer_Base.cpp
new file mode 100644
index 00000000000..084d6cf6c10
--- /dev/null
+++ b/TAO/tao/TransportCurrent/Current_ORBInitializer_Base.cpp
@@ -0,0 +1,75 @@
+// $Id$
+
+#include "tao/PI/ORBInitInfo.h"
+#include "tao/TransportCurrent/Current_ORBInitializer_Base.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ namespace Transport
+ {
+
+ Current_ORBInitializer_Base::Current_ORBInitializer_Base(const ACE_TCHAR* id)
+ : id_ (id)
+ {
+ }
+
+ Current_ORBInitializer_Base::~Current_ORBInitializer_Base(void)
+ {
+ }
+
+
+
+ void
+ Current_ORBInitializer_Base::pre_init (PortableInterceptor::ORBInitInfo_ptr info
+ ACE_ENV_ARG_DECL_NOT_USED )
+ ACE_THROW_SPEC( (CORBA::SystemException) )
+ {
+ // Narrow to a TAO_ORBInitInfo object to get access to the
+ // allocate_tss_slot_id() TAO extension.
+ TAO_ORBInitInfo_var tao_info =
+ TAO_ORBInitInfo::_narrow (info
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil (tao_info.in ()))
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) TAO::Transport::ORBInitializer::pre_init - "
+ "Panic: unable to narrow the ORBInitInfo_ptr\n"));
+
+ ACE_THROW (CORBA::INTERNAL ());
+ }
+
+ // Reserve a TSS slot in the ORB core internal TSS resources for the
+ // thread-specific portion of the Current object.
+ size_t tss_slot = tao_info->allocate_tss_slot_id (0
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Create the Current
+ Current_var current (this->make_current_instance (tao_info->orb_core (),
+ tss_slot
+ ACE_ENV_ARG_PARAMETER));
+
+ info->register_initial_reference (ACE_TEXT_ALWAYS_CHAR (this->id_.fast_rep ()),
+ current.in ());
+
+ }
+
+ void
+ Current_ORBInitializer_Base::post_init (PortableInterceptor::ORBInitInfo_ptr
+ ACE_ENV_ARG_DECL_NOT_USED )
+ ACE_THROW_SPEC( (CORBA::SystemException) )
+ {
+ }
+
+ }
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
diff --git a/TAO/tao/TransportCurrent/Current_ORBInitializer_Base.h b/TAO/tao/TransportCurrent/Current_ORBInitializer_Base.h
new file mode 100644
index 00000000000..77799dca1f4
--- /dev/null
+++ b/TAO/tao/TransportCurrent/Current_ORBInitializer_Base.h
@@ -0,0 +1,69 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Current_ORBInitializer_Base.h
+ *
+ * $Id$
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef CURRENT_ORBINITIALIZER_BASE_H
+#define CURRENT_ORBINITIALIZER_BASE_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/SString.h"
+#include "tao/PI/PI.h"
+
+#include "tao/TransportCurrent/Transport_Current_Export.h"
+#include "tao/TransportCurrent/TCC.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ namespace Transport
+ {
+
+ class TAO_Transport_Current_Export Current_ORBInitializer_Base :
+ public PortableInterceptor::ORBInitializer
+ {
+ public:
+ Current_ORBInitializer_Base (const ACE_TCHAR* id);
+ virtual ~Current_ORBInitializer_Base (void);
+
+ virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr
+ ACE_ENV_ARG_DECL_NOT_USED )
+ ACE_THROW_SPEC( (CORBA::SystemException) );
+
+ virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info
+ ACE_ENV_ARG_DECL_NOT_USED )
+ ACE_THROW_SPEC( (CORBA::SystemException) );
+
+ protected:
+ virtual TAO::Transport::Current_ptr
+ make_current_instance (TAO_ORB_Core* core,
+ size_t tss_slot_id
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException)) = 0;
+
+ protected:
+ const ACE_TString id_;
+ };
+
+ };
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* CURRENT_ORBINITIALIZER_BASE_H */
diff --git a/TAO/tao/TransportCurrent/IIOP_Current_Impl.cpp b/TAO/tao/TransportCurrent/IIOP_Current_Impl.cpp
new file mode 100644
index 00000000000..649cb6258ed
--- /dev/null
+++ b/TAO/tao/TransportCurrent/IIOP_Current_Impl.cpp
@@ -0,0 +1,124 @@
+// $Id$
+
+#include "ace/INET_Addr.h"
+#include "tao/IIOP_Connection_Handler.h"
+#include "tao/IIOP_Transport.h"
+#include "tao/Transport_Selection_Guard.h"
+
+#include "IIOP_Current_Impl.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ namespace Transport
+ {
+
+
+ /// Obtains the IIOP_Connection_Handler associated with the
+ /// Transport. Will throw NO_IMPLEMENT if the (selected) transport
+ /// () == 0, or if transport->connection_handler () == 0. Will
+ /// throw NoContext, if no transport has been selected yet.
+
+ TAO_IIOP_Connection_Handler*
+ IIOP_Current_Impl::handler (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ const TAO_Transport* t = this->transport ();
+ if (t == 0)
+ ACE_THROW_RETURN (::CORBA::NO_IMPLEMENT (), 0);
+
+ TAO_Connection_Handler *ch = const_cast<TAO_Transport*>(t)->connection_handler ();
+ if (ch == 0)
+ ACE_THROW_RETURN (::CORBA::NO_IMPLEMENT (), 0);
+
+ return static_cast <TAO_IIOP_Connection_Handler*> (ch);
+ }
+
+
+ /// Ctor
+
+ IIOP_Current_Impl::IIOP_Current_Impl (TAO_ORB_Core* core, size_t tss_slot_id)
+ : Current_Impl (core, tss_slot_id)
+ {
+ }
+
+
+ /// Dtor
+
+ IIOP_Current_Impl::~IIOP_Current_Impl (void)
+ {
+ }
+
+ CORBA::Long
+ IIOP_Current_Impl::id (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ return this->handler ()->get_handle ();
+ }
+
+ ::SSLIOP::Current_ptr
+ IIOP_Current_Impl::ssliop_current (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ ACE_THROW_RETURN (::CORBA::NO_IMPLEMENT (), 0);
+ }
+
+
+ CORBA::Long
+ IIOP_Current_Impl::remote_port (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ TAO_IIOP_Connection_Handler *iiopch =
+ this->handler ();
+
+ ACE_INET_Addr a;
+ iiopch->peer ().get_remote_addr (a);
+
+ return a.get_port_number ();
+ }
+
+ char*
+ IIOP_Current_Impl::remote_host (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ TAO_IIOP_Connection_Handler *iiopch =
+ this->handler ();
+
+ ACE_INET_Addr a;
+ iiopch->peer ().get_remote_addr (a);
+
+ return CORBA::string_dup (a.get_host_addr ());
+ }
+
+ CORBA::Long
+ IIOP_Current_Impl::local_port (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ TAO_IIOP_Connection_Handler *iiopch =
+ this->handler ();
+
+ ACE_INET_Addr a;
+ iiopch->peer ().get_local_addr (a);
+
+ return a.get_port_number ();
+ }
+
+ char*
+ IIOP_Current_Impl::local_host (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext))
+ {
+ TAO_IIOP_Connection_Handler *iiopch =
+ this->handler ();
+
+ ACE_INET_Addr a;
+ iiopch->peer ().get_local_addr (a);
+
+ return CORBA::string_dup (a.get_host_addr ());
+ }
+
+ }
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/TransportCurrent/IIOP_Current_Impl.h b/TAO/tao/TransportCurrent/IIOP_Current_Impl.h
new file mode 100644
index 00000000000..9ede80bec9a
--- /dev/null
+++ b/TAO/tao/TransportCurrent/IIOP_Current_Impl.h
@@ -0,0 +1,108 @@
+/**
+ * @file IIOP_Current_Impl.h
+ *
+ * @brief Provide implementation for the IIOPTraits interface
+ *
+ * $Id$
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ */
+
+#ifndef IIOP_CURRENT_IMPL_H
+#define IIOP_CURRENT_IMPL_H
+
+#include /**/ "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/TransportCurrent/TC_IIOPC.h"
+#include "tao/TransportCurrent/Current_Impl.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_Transport;
+class TAO_IIOP_Connection_Handler;
+
+namespace TAO
+{
+ namespace Transport
+ {
+
+ /**
+ * @class IIOP_Current_Impl
+ *
+ * @brief Implementation of the TAO::Transport::IIOPCurrent
+ * interface.
+ *
+ * IIOP_Current_Impl is useful for obtaining information about the
+ * IIOP Transport, associated with the calling thread.
+ */
+ class TAO_Transport_Current_Export IIOP_Current_Impl
+ : public virtual IIOP::Current
+ , public virtual Current_Impl
+ {
+ public:
+
+ /// Constructor.
+ IIOP_Current_Impl (TAO_ORB_Core* core, size_t tss_slot_id);
+
+ //@{
+ virtual ::CORBA::Long id (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+
+ virtual ::SSLIOP::Current_ptr ssliop_current (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+
+ virtual ::CORBA::Long remote_port (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+
+ virtual char* remote_host (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+
+ virtual ::CORBA::Long local_port (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+
+ virtual char* local_host (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+ //@}
+
+
+ protected:
+
+ /// Destructor
+ /**
+ * Protected destructor to enforce the fact this class is reference
+ * counted, and should not be destroyed using delete() by anything
+ * other than the reference counting mechanism.
+ */
+ virtual ~IIOP_Current_Impl (void);
+
+ private:
+
+ /// Returns the IIOP connection handler associated with the
+ /// Transport. Will throw NO_IMPLEMENT if the (selected) transport
+ /// () == 0, or if transport->connection_handler () == 0. Will
+ /// throw NoContext, if no transport has been selected yet.
+ TAO_IIOP_Connection_Handler* handler (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((::CORBA::SystemException, NoContext));
+
+ private:
+
+ /// Prevent copying through the copy constructor and
+ /// assignment operator.
+ //@{
+ IIOP_Current_Impl (const IIOP_Current_Impl &);
+ void operator= (const IIOP_Current_Impl &);
+ //@}
+
+ };
+ };
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* IIOP_CURRENT_IMPL_H */
diff --git a/TAO/tao/TransportCurrent/IIOP_Current_Loader.cpp b/TAO/tao/TransportCurrent/IIOP_Current_Loader.cpp
new file mode 100644
index 00000000000..b17da2f1a57
--- /dev/null
+++ b/TAO/tao/TransportCurrent/IIOP_Current_Loader.cpp
@@ -0,0 +1,95 @@
+/* -*- C++ -*- */
+
+// =================================================================
+/**
+ * @file IIOP_Current_Loader.cpp
+ *
+ * $Id$
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ *
+ */
+// =================================================================
+
+
+#include "ace/Service_Config.h"
+
+#include "tao/ORBInitializer_Registry.h"
+#include "tao/ORB_Constants.h"
+
+#include "tao/PI/PI.h"
+
+#include "tao/TransportCurrent/Current_ORBInitializer.h"
+#include "tao/TransportCurrent/IIOP_Current_Loader.h"
+#include "tao/TransportCurrent/IIOP_Current_Impl.h"
+
+ACE_RCSID (Transport_Current,
+ IIOP_Current_Loader,
+ "$Id$")
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ namespace Transport
+ {
+ namespace IIOP
+ {
+ /// Initializes object when dynamic linking occurs.
+ int
+ Current_Loader::init (int, ACE_TCHAR *[])
+ {
+ PortableInterceptor::ORBInitializer_ptr tmp = 0;
+ ACE_NEW_THROW_EX (tmp,
+ Current_ORBInitializer<IIOP_Current_Impl> (ACE_TEXT ("TAO::Transport::IIOP::Current")),
+ CORBA::NO_MEMORY (CORBA::SystemException::_tao_minor_code (TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+ ACE_TRY_CHECK;
+
+ PortableInterceptor::ORBInitializer_var initializer (tmp);
+
+ PortableInterceptor::register_orb_initializer (initializer.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ return 0;
+ }
+ }
+
+ }
+}
+
+
+#if defined (TAO_AS_STATIC_LIBS)
+ACE_STATIC_SVC_REQUIRE (TAO_Transport_IIOP_Current_Loader);
+
+namespace TAO
+{
+ namespace Transport
+ {
+ namespace IIOP
+ {
+ int current_static_initializer (void)
+ {
+ ACE_STATIC_SVC_REGISTER (TAO_Transport_IIOP_Current_Loader);
+ return 0;
+ }
+ }
+ }
+}
+#endif /* defined (TAO_AS_STATIC_LIBS) */
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+ACE_STATIC_SVC_DEFINE (TAO_Transport_IIOP_Current_Loader,
+ ACE_TEXT ("TAO_Transport_IIOP_Current_Loader"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_Transport_IIOP_Current_Loader),
+ ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+ACE_FACTORY_NAMESPACE_DEFINE (TAO_Transport_Current,
+ TAO_Transport_IIOP_Current_Loader,
+ TAO::Transport::IIOP::Current_Loader)
diff --git a/TAO/tao/TransportCurrent/IIOP_Current_Loader.h b/TAO/tao/TransportCurrent/IIOP_Current_Loader.h
new file mode 100644
index 00000000000..7f49533fa03
--- /dev/null
+++ b/TAO/tao/TransportCurrent/IIOP_Current_Loader.h
@@ -0,0 +1,68 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file IIOP_Current_Loader.h
+ *
+ * $Id$
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_TRANSPORT_IIOP_TRAITS_LOADER_H
+#define TAO_TRANSPORT_IIOP_TRAITS_LOADER_H
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/TransportCurrent/Current_Loader.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ namespace Transport
+ {
+
+ namespace IIOP
+ {
+ class TAO_Transport_Current_Export Current_Loader
+ : public TAO::Transport::Current_Loader
+ {
+ public:
+ /// Initializes object when dynamic linking occurs.
+ virtual int init (int argc, ACE_TCHAR *argv[]);
+ };
+ }
+ }
+}
+
+
+
+#if defined (TAO_AS_STATIC_LIBS)
+namespace TAO
+{
+ namespace Transport
+ {
+ namespace IIOP
+ {
+ int current_static_initializer (void);
+ }
+ }
+}
+
+#endif /* defined (TAO_AS_STATIC_LIBS) */
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Transport_Current,
+ TAO_Transport_IIOP_Current_Loader)
+
+ACE_FACTORY_DECLARE (TAO_Transport_Current,
+ TAO_Transport_IIOP_Current_Loader)
+
+#endif /* TAO_TRANSPORT_IIOP_TRAITS_LOADER_H */
diff --git a/TAO/tao/TransportCurrent/IIOP_Transport_Current.h b/TAO/tao/TransportCurrent/IIOP_Transport_Current.h
new file mode 100644
index 00000000000..9a59cc00f27
--- /dev/null
+++ b/TAO/tao/TransportCurrent/IIOP_Transport_Current.h
@@ -0,0 +1,17 @@
+// -*- C++ -*-
+// $Id$
+
+
+#include "tao/TransportCurrent/TCC.h"
+#include "tao/TransportCurrent/TC_IIOPC.h"
+#include "tao/TransportCurrent/IIOP_Current_Loader.h"
+
+#if defined (TAO_AS_STATIC_LIBS)
+
+// Only do this for static builds. It causes a circular dependency for
+// dynamic builds.
+static int tao_iiop_transport_current_initializer_called =
+ TAO::Transport::IIOP::current_static_initializer ();
+
+#endif /* TAO_AS_STATIC_LIBS */
+
diff --git a/TAO/tao/TransportCurrent/TC.idl b/TAO/tao/TransportCurrent/TC.idl
new file mode 100644
index 00000000000..6f6b5684790
--- /dev/null
+++ b/TAO/tao/TransportCurrent/TC.idl
@@ -0,0 +1,57 @@
+/**
+ * @file TC.idl
+ *
+ * @brief Defines the TAO::Transport::Current interface
+ *
+ * $Id$
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ */
+
+#ifndef TAO_TRANSPORT_CURRENT_IDL
+#define TAO_TRANSPORT_CURRENT_IDL
+
+#include <IOP.pidl>
+#include <TimeBase.pidl>
+
+module TAO
+{
+ /// A type used to represent counters
+ typedef unsigned long long CounterT;
+
+ module Transport
+ {
+ /// Used to signal that a call was made within improper invocation
+ /// context. Also, this exception is thrown if no Transport has
+ /// been selected for the current thread, for example in a
+ /// collocated invocation.
+
+ exception NoContext
+ {
+ };
+
+ // The primary interface, providing access to Transport
+ // information, available to the current thread.
+
+ local interface Current
+ {
+ /// Transport ID, unique within the process.
+ readonly attribute long id raises (NoContext);
+
+ /// Bytes sent/received through the transport.
+ readonly attribute CounterT bytes_sent raises (NoContext);
+ readonly attribute CounterT bytes_received raises (NoContext);
+
+ /// Messages (requests and replies) sent/received using the current
+ /// protocol.
+ readonly attribute CounterT messages_sent raises (NoContext);
+ readonly attribute CounterT messages_received raises (NoContext);
+
+ /// The absolute time (miliseconds) since the transport has been
+ /// open.
+ readonly attribute TimeBase::TimeT open_since raises (NoContext);
+ };
+ };
+};
+
+#endif /* TAO_TRANSPORT_CURRENT_IDL */
diff --git a/TAO/tao/TransportCurrent/TC.mpc b/TAO/tao/TransportCurrent/TC.mpc
new file mode 100644
index 00000000000..95a392e060b
--- /dev/null
+++ b/TAO/tao/TransportCurrent/TC.mpc
@@ -0,0 +1,33 @@
+//$Id:$
+
+project(*) : taolib_with_idl, tao_versioning_idl_defaults, core, interceptors, pi {
+
+ sharedname = TAO_TC
+ dynamicflags = TAO_TRANSPORT_CURRENT_BUILD_DLL
+
+ Source_Files {
+ Current_Impl.cpp
+ Current_Loader.cpp
+ Current_ORBInitializer_Base.cpp
+ }
+
+ Header_Files {
+ Current_Impl.h
+ Current_Loader.h
+ Current_ORBInitializer.h
+ Current_ORBInitializer_Base.h
+ Transport_Current.h
+ }
+
+ Template_Files {
+ Current_ORBInitializer.cpp
+ }
+
+ idlflags += -Wb,export_include=tao/TransportCurrent/Transport_Current_Export.h
+ idlflags += -Wb,export_macro=TAO_Transport_Current_Export
+
+ IDL_Files {
+ TC.idl
+ }
+}
+
diff --git a/TAO/tao/TransportCurrent/TC_IIOP.idl b/TAO/tao/TransportCurrent/TC_IIOP.idl
new file mode 100644
index 00000000000..17c87602d0a
--- /dev/null
+++ b/TAO/tao/TransportCurrent/TC_IIOP.idl
@@ -0,0 +1,56 @@
+/**
+ * @file TC_IIOP.idl
+ *
+ * @brief Defines the TAO::Transport::IIOP::Current interface
+ *
+ * $Id:$
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ */
+
+#ifndef TAO_TRANSPORT_IIOP_CURRENT_IDL
+#define TAO_TRANSPORT_IIOP_CURRENT_IDL
+
+#include "TC.idl"
+
+/// Provide a forward reference for the SSLIOP::Current
+module SSLIOP
+{
+ interface Current;
+};
+
+
+module TAO
+{
+ module Transport
+ {
+ module IIOP
+ {
+ // The primary interface, providing access to IIOP-specific
+ // transport information, if it is indeed an IIOP (-like) transport
+ // that has been selected.
+
+ local interface Current : TAO::Transport::Current
+ {
+ /// Remote host
+ readonly attribute string remote_host raises (NoContext);
+
+ /// Remote port Using long (signed) type to better accomodate
+ /// the Java mapping, which has no support for unsigned values
+ readonly attribute long remote_port raises (NoContext);
+
+ /// Local host
+ readonly attribute string local_host raises (NoContext);
+
+ /// Local port
+ readonly attribute long local_port raises (NoContext);
+
+ /// If this is a "secure" transport, this method will give you
+ /// the corresponding SSLIOP::Current
+ readonly attribute ::SSLIOP::Current ssliop_current raises (NoContext);
+ };
+ };
+ };
+};
+
+#endif /* TAO_TRANSPORT_IIOP_CURRENT_IDL */
diff --git a/TAO/tao/TransportCurrent/TC_IIOP.mpc b/TAO/tao/TransportCurrent/TC_IIOP.mpc
new file mode 100644
index 00000000000..1f28ceb549a
--- /dev/null
+++ b/TAO/tao/TransportCurrent/TC_IIOP.mpc
@@ -0,0 +1,27 @@
+//$Id:$
+
+project(*) : taolib_with_idl, tao_versioning_idl_defaults, core, interceptors, pi, tc {
+
+ sharedname = TAO_TC_IIOP
+
+ dynamicflags = TAO_TRANSPORT_CURRENT_BUILD_DLL
+ libs += TAO_TC
+
+ Source_Files {
+ IIOP_Current_Impl.cpp
+ IIOP_Current_Loader.cpp
+ }
+
+ Header_Files {
+ IIOP_Current_Impl.h
+ IIOP_Current_Loader.h
+ IIOP_Transport_Current.h
+ }
+
+ idlflags += -Wb,export_include=tao/TransportCurrent/Transport_Current_Export.h
+ idlflags += -Wb,export_macro=TAO_Transport_Current_Export
+
+ IDL_Files {
+ TC_IIOP.idl
+ }
+}
diff --git a/TAO/tao/TransportCurrent/Transport_Current.h b/TAO/tao/TransportCurrent/Transport_Current.h
new file mode 100644
index 00000000000..2d776e8d6b6
--- /dev/null
+++ b/TAO/tao/TransportCurrent/Transport_Current.h
@@ -0,0 +1,16 @@
+// -*- C++ -*-
+// $Id$
+
+
+#include "tao/TransportCurrent/TCC.h"
+#include "tao/TransportCurrent/Current_Loader.h"
+
+#if defined (TAO_AS_STATIC_LIBS)
+
+// Only do this for static builds. It causes a circular dependency for
+// dynamic builds.
+static int tao_transport_current_initializer_called =
+ TAO::Transport::current_static_initializer ();
+
+#endif /* TAO_AS_STATIC_LIBS */
+
diff --git a/TAO/tao/TransportCurrent/Transport_Current_Export.h b/TAO/tao/TransportCurrent/Transport_Current_Export.h
new file mode 100644
index 00000000000..ce01b4dc2f1
--- /dev/null
+++ b/TAO/tao/TransportCurrent/Transport_Current_Export.h
@@ -0,0 +1,54 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -d TAO_Transport_Current
+// ------------------------------
+#ifndef TAO_TRANSPORT_CURRENT_EXPORT_H
+#define TAO_TRANSPORT_CURRENT_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if !defined (TAO_TRANSPORT_CURRENT_HAS_DLL)
+# define TAO_TRANSPORT_CURRENT_HAS_DLL 1
+#endif /* ! TAO_TRANSPORT_CURRENT_HAS_DLL */
+
+#if defined (TAO_TRANSPORT_CURRENT_HAS_DLL) && (TAO_TRANSPORT_CURRENT_HAS_DLL == 1)
+# if defined (TAO_TRANSPORT_CURRENT_BUILD_DLL)
+# define TAO_Transport_Current_Export ACE_Proper_Export_Flag
+# define TAO_TRANSPORT_CURRENT_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define TAO_TRANSPORT_CURRENT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* TAO_TRANSPORT_CURRENT_BUILD_DLL */
+# define TAO_Transport_Current_Export ACE_Proper_Import_Flag
+# define TAO_TRANSPORT_CURRENT_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define TAO_TRANSPORT_CURRENT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* TAO_TRANSPORT_CURRENT_BUILD_DLL */
+#else /* TAO_TRANSPORT_CURRENT_HAS_DLL == 1 */
+# define TAO_Transport_Current_Export
+# define TAO_TRANSPORT_CURRENT_SINGLETON_DECLARATION(T)
+# define TAO_TRANSPORT_CURRENT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* TAO_TRANSPORT_CURRENT_HAS_DLL == 1 */
+
+// Set TAO_TRANSPORT_CURRENT_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (TAO_TRANSPORT_CURRENT_NTRACE)
+# if (ACE_NTRACE == 1)
+# define TAO_TRANSPORT_CURRENT_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define TAO_TRANSPORT_CURRENT_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !TAO_TRANSPORT_CURRENT_NTRACE */
+
+#if (TAO_TRANSPORT_CURRENT_NTRACE == 1)
+# define TAO_TRANSPORT_CURRENT_TRACE(X)
+#else /* (TAO_TRANSPORT_CURRENT_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define TAO_TRANSPORT_CURRENT_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (TAO_TRANSPORT_CURRENT_NTRACE == 1) */
+
+#endif /* TAO_TRANSPORT_CURRENT_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/tao/Transport_Selection_Guard.cpp b/TAO/tao/Transport_Selection_Guard.cpp
new file mode 100644
index 00000000000..bd1164131df
--- /dev/null
+++ b/TAO/tao/Transport_Selection_Guard.cpp
@@ -0,0 +1,81 @@
+// $Id$
+
+#include "tao/Transport_Selection_Guard.h"
+#include "tao/TSS_Resources.h"
+
+ACE_RCSID (tao,
+ Transport_Selection_Guard.cpp,
+ "$Id$")
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ Transport_Selection_Guard*
+ Transport_Selection_Guard::current (TAO_ORB_Core* core, size_t tss_slot_id)
+ {
+ // @NOTE: (Iliyan) Started making this method aware of the core
+ // and the tss slot that correspond to the "current" transport,
+ // influenced by a general design preference to keep things
+ // local. The idea was to make the current TSG part of the TSS
+ // storage for a specific ORB Core, as opposed to using the global
+ // TSS Resources. However, it really doesn't offer any benefit to
+ // store a Transport pointer locally, for each ORB. There is
+ // always only one current Transport per thread. Period. The
+ // number of ORB Core instances in existence does not change that
+ // fact, so keeping a separate pointer would have been an
+ // over-kill.
+ ACE_UNUSED_ARG (core);
+ ACE_UNUSED_ARG (tss_slot_id);
+
+#if TAO_HAS_TRANSPORT_CURRENT == 1
+
+ return TAO_TSS_Resources::instance ()->tsg_;
+
+#else /* TAO_HAS_TRANSPORT_CURRENT != 1 */
+
+ return 0;
+
+#endif /* TAO_HAS_TRANSPORT_CURRENT == 1 */
+ };
+
+
+
+ /// Ctor
+ Transport_Selection_Guard::Transport_Selection_Guard (TAO_Transport* t)
+ :
+#if TAO_HAS_TRANSPORT_CURRENT == 1
+
+ prev_ (TAO_TSS_Resources::instance ()->tsg_)
+ ,
+
+#endif /* TAO_HAS_TRANSPORT_CURRENT == 1 */
+ curr_ (t)
+ {
+#if TAO_HAS_TRANSPORT_CURRENT == 1
+
+ TAO_TSS_Resources::instance ()->tsg_ = this;
+
+#endif /* TAO_HAS_TRANSPORT_CURRENT == 1 */
+
+ };
+
+
+
+ /// Dtor
+ Transport_Selection_Guard::~Transport_Selection_Guard (void)
+ {
+
+#if TAO_HAS_TRANSPORT_CURRENT == 1
+
+ TAO_TSS_Resources::instance ()->tsg_ = prev_;
+ this->prev_ = 0;
+
+#endif /* TAO_HAS_TRANSPORT_CURRENT == 1 */
+ this->curr_ = 0;
+ };
+
+} /* namespace TAO */
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Transport_Selection_Guard.h b/TAO/tao/Transport_Selection_Guard.h
new file mode 100644
index 00000000000..96f3deac271
--- /dev/null
+++ b/TAO/tao/Transport_Selection_Guard.h
@@ -0,0 +1,125 @@
+// -*- C++ -*-
+
+// ===================================================================
+/**
+ * @file Transport_Selection_Guard.h
+ *
+ * $Id$
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ */
+// ===================================================================
+
+#ifndef TAO_TRANSPORT_SELECTION_GUARD_H
+#define TAO_TRANSPORT_SELECTION_GUARD_H
+
+#include /**/ "ace/pre.h"
+
+#include "tao/TAO_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Environment.h"
+
+/* #include "tao/Policy_Current_Impl.h" */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+// Forward declarations
+class TAO_Transport;
+
+namespace TAO
+{
+ /**
+ * @class Transport_Selection_Guard
+ *
+ * @brief Used by the Transport Current feature to keep track of
+ * which Transport is currently active.
+ *
+ * Whenever a Transport is selected: during an upcall, or prior to a
+ * client invocation an instance of this class is created [on the
+ * stack, or as a member of another class] to keep track of the said
+ * Transport. The class implements the RAII idiom, which makes it
+ * possible to build a stack of these instances as the thread is
+ * doing nested upcalls or client invocations.
+ *
+ * It utilizes TAO_TSS_Resources::tsg_ member pointer to keep track
+ * of stack-linked Transport_Selection_Guard instances.
+ *
+ * If the Transport Current feature is disabled most methods are
+ * no-ops and add no overhead on the critical path.
+ *
+ * <B>See Also:</B>
+ *
+ * https://svn.dre.vanderbilt.edu/viewvc/Middleware/trunk/TAO/docs/transport_current/index.html?revision=HEAD
+ *
+ */
+ class TAO_Export Transport_Selection_Guard
+ {
+ public:
+
+ static Transport_Selection_Guard* current (TAO_ORB_Core* core,
+ size_t tss_slot_id);
+
+ public:
+
+ /// Ctor
+ Transport_Selection_Guard (TAO_Transport* t);
+
+ /// Dtor
+ ~Transport_Selection_Guard (void);
+
+ /// getter
+ TAO_Transport* operator-> (void) const
+ {
+ return this->get ();
+ };
+
+ /// getter
+ TAO_Transport& operator* (void) const
+ {
+ return *this->get ();
+ };
+
+ /// Getter
+ TAO_Transport* get (void) const
+ {
+ return this->curr_;
+ };
+
+ /// Setter
+ Transport_Selection_Guard& set (TAO_Transport* t)
+ {
+ this->curr_ = t;
+ return *this;
+ };
+
+ private:
+ ACE_UNIMPLEMENTED_FUNC (Transport_Selection_Guard (const Transport_Selection_Guard&))
+ ACE_UNIMPLEMENTED_FUNC (Transport_Selection_Guard& operator=(const Transport_Selection_Guard&))
+
+#if TAO_HAS_TRANSPORT_CURRENT == 1
+
+ /// This is pointing to the guard that was active prior to
+ /// instantiating us.
+
+ Transport_Selection_Guard* prev_;
+
+#endif /* TAO_HAS_TRANSPORT_CURRENT == 1 */
+
+ /// The "real" Transport, i.e. the one selected at present
+ TAO_Transport* curr_;
+ };
+
+} /* namespace TAO */
+
+
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_TRANSPORT_SELECTION_GUARD_H */
diff --git a/TAO/tao/orbconf.h b/TAO/tao/orbconf.h
index 541e08b56fd..69404326b05 100644
--- a/TAO/tao/orbconf.h
+++ b/TAO/tao/orbconf.h
@@ -839,6 +839,12 @@ enum TAO_Policy_Scope
# define TAO_USE_OUTPUT_CDR_MMAP_MEMORY_POOL 0
#endif /* TAO_USE_LOCAL_MEMORY_POOL */
+// Enable TransportCurrent by default
+#if !defined (TAO_HAS_TRANSPORT_CURRENT)
+# define TAO_HAS_TRANSPORT_CURRENT 1
+# else
+# define TAO_HAS_TRANSPORT_CURRENT 0
+#endif /* ! TAO_HAS_TRANSPORT_CURRENT */
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/tao.mpc b/TAO/tao/tao.mpc
index e504d5b7490..ac16584db90 100644
--- a/TAO/tao/tao.mpc
+++ b/TAO/tao/tao.mpc
@@ -222,6 +222,7 @@ project(TAO) : acelib, core, tao_output, taodefaults, pidl, extra_core, tao_vers
Transport_Descriptor_Interface.cpp
Transport_Mux_Strategy.cpp
Transport_Queueing_Strategies.cpp
+ Transport_Selection_Guard.cpp
Transport_Timer.cpp
TSS_Resources.cpp
TypeCodeFactory_Adapter.cpp
@@ -529,6 +530,7 @@ project(TAO) : acelib, core, tao_output, taodefaults, pidl, extra_core, tao_vers
Transport.h
Transport_Mux_Strategy.h
Transport_Queueing_Strategies.h
+ Transport_Selection_Guard.h
Transport_Timer.h
TSS_Resources.h
TypeCodeFactory_Adapter.h
diff --git a/TAO/tests/TransportCurrent/Framework/Client_Request_Interceptor.cpp b/TAO/tests/TransportCurrent/Framework/Client_Request_Interceptor.cpp
new file mode 100644
index 00000000000..51e7fa04b31
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/Client_Request_Interceptor.cpp
@@ -0,0 +1,182 @@
+// -*- C++ -*-
+
+#include "ace/Log_Msg.h"
+
+ACE_RCSID (ForwardRequest,
+ Client_Request_Interceptor,
+ "$Id$")
+
+#include "Current_TestC.h"
+#include "Client_Request_Interceptor.h"
+#include "ORBInitializer_T.h"
+
+// // A specialization to handle client-side interceptors
+// template <>
+// void ORBInitializer<PortableInterceptor::ClientRequestInterceptor>::post_init
+// (PortableInterceptor::ORBInitInfo* oii ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+// ACE_THROW_SPEC ((CORBA::SystemException));
+
+
+namespace Test
+{
+
+ using namespace TAO;
+
+ // A specialization to handle client-side interceptors
+ template <>
+ void
+ ORBInitializer<PortableInterceptor::ClientRequestInterceptor>::post_init (PortableInterceptor::ORBInitInfo* oii
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ oii->add_client_request_interceptor (this->interceptor_.in ());
+ };
+
+ Client_Request_Interceptor::Client_Request_Interceptor (const char *orb_id,
+ TEST test)
+ : orb_id_ (CORBA::string_dup (orb_id))
+ , request_count_ (0)
+ , requestID_ (1)
+ , test_ (test)
+ {
+ }
+
+ CORBA::Long
+ Client_Request_Interceptor::interceptions (void)
+ {
+ return this->request_count_;
+ }
+
+ char *
+ Client_Request_Interceptor::name (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ return CORBA::string_dup ("Client_Request_Interceptor");
+ }
+
+ void
+ Client_Request_Interceptor::test_transport_current (const ACE_TCHAR* amethod
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ CORBA::UserException))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("CRI (%P|%t) Test accessing Transport Current from %s\n"),
+ amethod));
+
+ ++this->request_count_;
+
+ int tmp = 0;
+ CORBA::ORB_var orb = CORBA::ORB_init (tmp,
+ 0,
+ orb_id_.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ (*this->test_) (orb.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("CRI (%P|%t) Successfully tested Transport Current from %s\n"),
+ amethod));
+ }
+
+ void
+ Client_Request_Interceptor::destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ }
+
+ void
+ Client_Request_Interceptor::send_request (PortableInterceptor::ClientRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest))
+ {
+ //Test TC
+
+ test_transport_current ("send_request"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ CORBA::Boolean response_expected =
+ ri->response_expected (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Oneway?
+ if (response_expected)
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("CRI (%P|%t) Sending a two-way\n")));
+ else
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("CRI (%P|%t) Sending a one-way\n")));
+
+ // Make the context to send the context to the target
+
+ IOP::ServiceContext sc;
+ sc.context_id = TAO::Transport::CurrentTest::ContextTag;
+
+ char temp[100];
+ {
+ ACE_GUARD (TAO_SYNCH_MUTEX, monitor, this->lock_);
+
+ ACE_OS::sprintf (temp, "%d", this->requestID_);
+ this->requestID_++;
+ }
+
+ CORBA::ULong string_len = ACE_OS::strlen (temp) + 1;
+ CORBA::Octet *buf = CORBA::OctetSeq::allocbuf (string_len);
+ ACE_OS::strcpy (ACE_reinterpret_cast (char *, buf), temp);
+
+ 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 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ }
+
+ void
+ Client_Request_Interceptor::send_poll (PortableInterceptor::ClientRequestInfo_ptr
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ test_transport_current ("send_poll"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ void
+ Client_Request_Interceptor::receive_reply (PortableInterceptor::ClientRequestInfo_ptr
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ test_transport_current ("receive_reply"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ void
+ Client_Request_Interceptor::receive_exception (PortableInterceptor::ClientRequestInfo_ptr
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest))
+ {
+ test_transport_current ("receive_exception"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ void
+ Client_Request_Interceptor::receive_other (PortableInterceptor::ClientRequestInfo_ptr
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest))
+ {
+
+ test_transport_current ("receive_other"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ }
+
+}
diff --git a/TAO/tests/TransportCurrent/Framework/Client_Request_Interceptor.h b/TAO/tests/TransportCurrent/Framework/Client_Request_Interceptor.h
new file mode 100644
index 00000000000..4c35f70aba6
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/Client_Request_Interceptor.h
@@ -0,0 +1,144 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Client_Request_Interceptor.h
+ *
+ * $Id$
+ *
+ * Implementation header for the client request interceptor for the
+ * Transport::Current test.
+ *
+ * @author Ossama Othman <ossama@uci.edu>
+ */
+//=============================================================================
+
+#ifndef CLIENT_REQUEST_INTERCEPTOR_H
+#define CLIENT_REQUEST_INTERCEPTOR_H
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/PI/PI.h"
+#include "tao/PortableInterceptorC.h"
+#include "tao/LocalObject.h"
+#include "tao/ORB.h"
+#include "tao/CORBA_String.h"
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4250)
+#endif /* _MSC_VER */
+
+
+namespace Test
+{
+
+ /// A metod doing the actual testing, so we could change it for the
+ /// different traits implementations
+
+ typedef int (*TEST) (CORBA::ORB_ptr ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+
+
+ /**
+ * @class Client_Request_Interceptor
+ *
+ * @brief Client request interceptor that exercises
+ * Transport::Current support.
+ *
+ * This client request interceptor forwards a request to a secondary
+ * object by throwing the PortableInterceptor::ForwardRequest
+ * exception from within the send_request() interception point. It
+ * only forwards the initial request. See the README file for
+ * details.
+ */
+ class Client_Request_Interceptor
+ : public virtual PortableInterceptor::ClientRequestInterceptor,
+ public virtual TAO_Local_RefCounted_Object
+ {
+ public:
+
+ /// Constructor.
+ Client_Request_Interceptor (const char *orb_id,
+ TEST test);
+ /**
+ * @name Methods Required by the Client 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 client request interceptors.
+ */
+ //@{
+ /// Return the name of this ClientRequestinterceptor.
+ virtual char * name (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual void destroy (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual void send_request (PortableInterceptor::ClientRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest));
+
+ virtual void send_poll (PortableInterceptor::ClientRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual void receive_reply (PortableInterceptor::ClientRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual void receive_exception (PortableInterceptor::ClientRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest));
+
+ virtual void receive_other (PortableInterceptor::ClientRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest));
+ //@}
+
+ CORBA::Long interceptions (void);
+
+ private:
+ void test_transport_current (const ACE_TCHAR* amethod ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException, CORBA::UserException));
+
+ private:
+ ///The ID of the ORB this interceptor is registered with.
+ CORBA::String_var orb_id_;
+
+ /// Pseudo-reference to the ORB this interceptor is registered
+ /// with.
+ CORBA::ORB_var orb_;
+
+ /// The number of requests intercepted by this interceptor.
+ CORBA::ULong request_count_;
+
+ /// Stringified reference to the object the initial request will be
+ /// forwarded to by this interceptor.
+ CORBA::String_var forward_str_;
+
+ /// Synchronize internal state...
+ TAO_SYNCH_MUTEX lock_;
+
+ /// Unique request ID
+ unsigned long requestID_;
+
+ /// Test function
+ TEST test_;
+ };
+
+}; // namespace Test
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif /* _MSC_VER */
+
+#endif /* CLIENT_REQUEST_INTERCEPTOR_H */
diff --git a/TAO/tests/TransportCurrent/Framework/Current_Test.idl b/TAO/tests/TransportCurrent/Framework/Current_Test.idl
new file mode 100644
index 00000000000..419be426991
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/Current_Test.idl
@@ -0,0 +1,34 @@
+// -*- IDL -*-
+
+//=============================================================================
+/**
+ * @file test.idl
+ *
+ * $Id$
+ *
+ * Simple IDL file to test TAO::TranspotCurrent
+ * support.
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ */
+//=============================================================================
+
+module TAO
+{
+ module Transport
+ {
+ interface CurrentTest
+ {
+
+ const unsigned long ContextTag = 0xabcdef;
+
+ void invoked_by_client ();
+
+ void invoked_during_upcall ();
+
+ long self_test ();
+
+ oneway void shutdown ();
+ };
+ };
+};
diff --git a/TAO/tests/TransportCurrent/Framework/Current_Test_Impl.cpp b/TAO/tests/TransportCurrent/Framework/Current_Test_Impl.cpp
new file mode 100644
index 00000000000..6b3eea3d891
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/Current_Test_Impl.cpp
@@ -0,0 +1,169 @@
+// -*- C++ -*-
+
+#include "tao/TransportCurrent/TCC.h"
+
+#include "Current_Test_Impl.h"
+
+ACE_RCSID (Transport_Current,
+ Current_Test_Impl,
+ "$Id$")
+
+ Current_Test_Impl::Current_Test_Impl (CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ int do_collocated_calls)
+ : orb_ (CORBA::ORB::_duplicate (orb))
+ , poa_ (PortableServer::POA::_duplicate (poa))
+ , do_collocated_calls_ (do_collocated_calls)
+{
+}
+
+Current_Test_Impl::~Current_Test_Impl (void)
+{
+}
+
+::CORBA::Long
+Current_Test_Impl::self_test (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((::CORBA::SystemException))
+{
+ return 0;
+}
+
+void
+Current_Test_Impl::test_transport_current (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (TAO_debug_level > 2) {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - Testing access to Transport Current ...\n")));
+ }
+
+ CORBA::Object_var tcobject =
+ orb_->resolve_initial_references ("TAO::Transport::Current"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ TAO::Transport::Current_var tc =
+ TAO::Transport::Current::_narrow (tcobject.in ()
+ ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ if (TAO_debug_level >= 1)
+ {
+ ::CORBA::Long id = tc->id (ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT bs = tc->bytes_sent (ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT br = tc->bytes_received (ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT rs = tc->messages_sent (ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT rr = tc->messages_received (ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Current_Test_Impl (%P|%t) Transport [%q] - Sent/Received [bytes=%q/%q, messages=%q/%q]\n"),
+ (ACE_UINT64)id,
+ (ACE_UINT64)bs,
+ (ACE_UINT64)br,
+ (ACE_UINT64)rs,
+ (ACE_UINT64)rr));
+ }
+
+ if (TAO_debug_level > 2) {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - Successfully accessed Transport Current\n")));
+ }
+}
+
+void
+Current_Test_Impl::invoked_by_client (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_TRY
+ {
+ this->invoked_by_client_i (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (TAO::Transport::NoContext, ex)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) server - Caught a Transport::NoContext exception\n")));
+ }
+ ACE_CATCH (CORBA::SystemException, ex1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) server - Caught a CORBA::SystemException exception\n")));
+ }
+ ACE_ENDTRY;
+}
+
+void
+Current_Test_Impl::invoked_by_client_i (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException, TAO::Transport::NoContext))
+{
+ if (TAO_debug_level > 2) {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - Testing inside an upcall\n")));
+ }
+
+ this->test_transport_current (ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ if (this->do_collocated_calls_)
+ {
+ CORBA::Object_var selfobject =
+ poa_->servant_to_reference (this
+ ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ TAO::Transport::CurrentTest_var self =
+ TAO::Transport::CurrentTest::_narrow (selfobject.in ()
+ ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ if (TAO_debug_level >= 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - Testing a collocated call\n")));
+ }
+ self->invoked_during_upcall (ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ else
+ {
+ if (TAO_debug_level >= 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - Skipping the collocated call test\n")));
+ }
+ }
+}
+
+void
+Current_Test_Impl::invoked_during_upcall (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (TAO_debug_level > 2) {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - Test method invoked ")
+ ACE_TEXT ("by the server during upcall.\n")));
+ }
+
+}
+
+void
+Current_Test_Impl::shutdown (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (TAO_debug_level > 2) {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - shutting down.\n")));
+ }
+
+ this->orb_->shutdown (0
+ ACE_ENV_ARG_PARAMETER);
+}
diff --git a/TAO/tests/TransportCurrent/Framework/Current_Test_Impl.h b/TAO/tests/TransportCurrent/Framework/Current_Test_Impl.h
new file mode 100644
index 00000000000..8e589cc84dc
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/Current_Test_Impl.h
@@ -0,0 +1,80 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Current_Test_Impl.h
+ *
+ * $Id$
+ *
+ * Implementation header for the "test" IDL interface for the
+ * TAO::TransportCurrent test.
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef CURRENT_TEST_IMPL_H
+#define CURRENT_TEST_IMPL_H
+
+#include "Current_TestS.h"
+#include "tao/TransportCurrent/TCC.h"
+
+/**
+ * @class Current_Test_Impl
+ *
+ * @brief Simple test class.
+ *
+ * This class implements the "test" interface used in this test.
+ */
+class Current_Test_Impl : public virtual POA_TAO::Transport::CurrentTest
+{
+public:
+
+ /// Constructor.
+ Current_Test_Impl (CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, int do_collocated_calls = 1);
+
+ /// Destructor.
+ ~Current_Test_Impl (void);
+
+ /// Main servant test method.
+ virtual void invoked_by_client (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// No-op method used so that a client request interceptor will be
+ /// invoked when invoking this method from the above invoke_me()
+ /// method. Say that 10 times fast. :-)
+ virtual void invoked_during_upcall (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// Shutdown the ORB.
+ virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual ::CORBA::Long self_test (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((::CORBA::SystemException));
+
+public:
+ /// Reports if unexpected errors have been encountered for the
+ /// lifetime of the instance
+ bool is_successful (void) const;
+
+private:
+ void test_transport_current (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// Main servant test method.
+ void invoked_by_client_i (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((::CORBA::SystemException, TAO::Transport::NoContext));
+
+private:
+ /// Pseudo-reference to the ORB.
+ CORBA::ORB_var orb_;
+
+ /// Pseudo-reference to the POA (cache)
+ PortableServer::POA_var poa_;
+
+ ///
+ int do_collocated_calls_;
+};
+
+#endif /* CURRENT_TEST_IMPL_H */
diff --git a/TAO/tests/TransportCurrent/Framework/Framework.mpc b/TAO/tests/TransportCurrent/Framework/Framework.mpc
new file mode 100644
index 00000000000..74ca4a0d856
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/Framework.mpc
@@ -0,0 +1,27 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): taoserver, tc, pi_server {
+ Source_Files {
+ server.cpp
+ Current_Test_Impl.cpp
+ Server_Request_Interceptor.cpp
+ Tester.cpp
+ Server_Main.cpp
+ }
+ IDL_Files {
+ Current_Test.idl
+ }
+}
+
+project(*Client): taoclient, tc, pi, dynamicinterface {
+ after += *Server
+ Source_Files {
+ Client_Request_Interceptor.cpp
+ client.cpp
+ Tester.cpp
+ }
+ IDL_Files {
+ Current_Test.idl
+ }
+}
diff --git a/TAO/tests/TransportCurrent/Framework/ORBInitializer_T.h b/TAO/tests/TransportCurrent/Framework/ORBInitializer_T.h
new file mode 100644
index 00000000000..c62e53fefb9
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/ORBInitializer_T.h
@@ -0,0 +1,62 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ORBInitializer_T.h
+ *
+ * $Id$
+ *
+ * @author Iliyan jeliazkov <iliyan@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORBINITIALIZER_T_H
+#define ORBINITIALIZER_T_H
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/PI/PI.h"
+#include "tao/PortableInterceptorC.h"
+/* #include "tao/LocalObject.h" */
+/* #include "tao/ORB.h" */
+/* #include "tao/CORBA_String.h" */
+
+namespace Test
+{
+ // A template class for ORBInitializer, which registers
+ // interceptors. Partial specializations exist to handle client and
+ // server request interceptors.
+ template <typename Interceptor>
+ class ORBInitializer : public PortableInterceptor::ORBInitializer
+ {
+ public:
+ ORBInitializer (typename Interceptor::_ptr_type interceptor)
+ : interceptor_ (Interceptor::_duplicate (interceptor))
+ {
+ };
+
+ ~ORBInitializer (void)
+ {
+ };
+
+ virtual void pre_init(PortableInterceptor::ORBInitInfo* ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ };
+
+ virtual void post_init(PortableInterceptor::ORBInitInfo* ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ private:
+ typename Interceptor::_var_type interceptor_;
+ };
+
+};
+
+#endif /* ORBINITIALIZER_T_H */
+
+
diff --git a/TAO/tests/TransportCurrent/Framework/README b/TAO/tests/TransportCurrent/Framework/README
new file mode 100644
index 00000000000..4ca496c01a5
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/README
@@ -0,0 +1,22 @@
+This test intents to show the usage and the expected behavior of the
+Transport Current framework. The topology is the same as in the basic
+Hello test: a client invokes a method on the server and then shuts it
+down and exits. The special features of the test is that it attempts
+to obtain Transport Traits information, using the Transport Current.
+
+There are four basic contexts in which a Transport information can be
+requested, by definition:
+
+ * on the client side, outside client-side interceptor;
+ * client side, inside an interceptor;
+ * server side, inside an up-call;
+ * server side, inside an interceptor;
+
+The test implements the client and the server side interceptors that
+simply call a test method when invoked. A simple interception count
+serves to validate the expected behavior.
+
+By default, the client and server will each have only one thread. Use
+"-t N" parameter to override that. The "-n N" client-side parameter
+determines how many times a particular client thread will call the
+server. The default is 1.
diff --git a/TAO/tests/TransportCurrent/Framework/Server_Main.cpp b/TAO/tests/TransportCurrent/Framework/Server_Main.cpp
new file mode 100644
index 00000000000..21c1227fbf3
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/Server_Main.cpp
@@ -0,0 +1,23 @@
+// -*- C++ -*-
+
+// $Id$
+
+#include "Server_Request_Interceptor.h"
+
+/// Prototype
+int server_main (int argc,
+ ACE_TCHAR *argv[],
+ Test::Server_Request_Interceptor *cri);
+
+int
+test_transport_current (CORBA::ORB_ptr orb
+ ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException,
+ CORBA::UserException));
+
+int
+ACE_TMAIN (int argc,
+ ACE_TCHAR *argv[])
+{
+ Test::Server_Request_Interceptor cri ("test_orb", test_transport_current);
+ return server_main (argc, argv, &cri);
+}
diff --git a/TAO/tests/TransportCurrent/Framework/Server_Request_Interceptor.cpp b/TAO/tests/TransportCurrent/Framework/Server_Request_Interceptor.cpp
new file mode 100644
index 00000000000..26062f02c97
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/Server_Request_Interceptor.cpp
@@ -0,0 +1,164 @@
+// -*- C++ -*-
+
+#include "ace/Log_Msg.h"
+//#include "ace/Global_Macros.h"
+#include "tao/ORB_Constants.h"
+
+
+ACE_RCSID (ForwardRequest,
+ Server_Request_Interceptor,
+ "$Id$")
+
+#include "Server_Request_Interceptor.h"
+
+namespace Test {
+
+ using namespace TAO;
+
+ // A specialization to handle server-side interceptors
+ template <>
+ void
+ ORBInitializer<PortableInterceptor::ServerRequestInterceptor>::post_init (PortableInterceptor::ORBInitInfo* oii
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ oii->add_server_request_interceptor (this->interceptor_.in ());
+ }
+
+
+
+ Server_Request_Interceptor::Server_Request_Interceptor (const char* orbid, TEST test)
+ : request_count_ (0)
+ , orb_id_ (::CORBA::string_dup (orbid))
+ , test_ (test)
+ {
+ }
+
+ Server_Request_Interceptor::~Server_Request_Interceptor (void)
+ {
+ }
+
+ void
+ Server_Request_Interceptor::test_transport_current (const ACE_TCHAR* amethod
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ CORBA::String_var name (this->name ());
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%s (%P|%t) Test accessing Transport Current from %s\n"),
+ name.in (),
+ amethod));
+
+ ++this->request_count_;
+
+ if (TAO_debug_level >=1)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%s (%P|%t) Getting the ORB\n"),
+ name.in ()));
+
+ int tmpargc = 0;
+ CORBA::ORB_var orb = CORBA::ORB_init (tmpargc,
+ 0,
+ this->orb_id_.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (TAO_debug_level >=1)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%s (%P|%t) Resolving the TC\n"),
+ name.in ()));
+
+ CORBA::Object_var tcobject =
+ orb->resolve_initial_references ("TAO::Transport::Current"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ (*this->test_) (orb.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%s (%P|%t) Success - Transport Current from %s\n"),
+ name.in (),
+ amethod));
+ }
+
+ /// queries the status of the test
+ bool
+ Server_Request_Interceptor::self_test () const
+ {
+ return true;
+ }
+
+
+ char *
+ Server_Request_Interceptor::name (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ return CORBA::string_dup ("SRI ");
+ }
+
+ void
+ Server_Request_Interceptor::destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ }
+
+ void
+ Server_Request_Interceptor::receive_request_service_contexts (PortableInterceptor::ServerRequestInfo_ptr
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest))
+ {
+ test_transport_current ("receive_request_service_contexts"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ }
+
+ void
+ Server_Request_Interceptor::receive_request (PortableInterceptor::ServerRequestInfo_ptr
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest))
+ {
+ test_transport_current ("receive_request"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ }
+
+ void
+ Server_Request_Interceptor::send_reply (PortableInterceptor::ServerRequestInfo_ptr
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ test_transport_current ("send_reply"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ void
+ Server_Request_Interceptor::send_exception (PortableInterceptor::ServerRequestInfo_ptr
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest))
+ {
+ test_transport_current ("send_exception"
+ ACE_ENV_ARG_PARAMETER);
+
+ ACE_CHECK;
+ }
+
+ void
+ Server_Request_Interceptor::send_other (PortableInterceptor::ServerRequestInfo_ptr
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest))
+ {
+ test_transport_current ("send_other"
+ ACE_ENV_ARG_PARAMETER);
+
+ ACE_CHECK;
+ }
+
+} /* namespace Test */
diff --git a/TAO/tests/TransportCurrent/Framework/Server_Request_Interceptor.h b/TAO/tests/TransportCurrent/Framework/Server_Request_Interceptor.h
new file mode 100644
index 00000000000..8dffec9ab9a
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/Server_Request_Interceptor.h
@@ -0,0 +1,139 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Server_Request_Interceptor.h
+ *
+ * $Id$
+ *
+ * Implementation header for the server request interceptor for the
+ * PortableInterceptor::ForwardRequest test.
+ *
+ * @author Ossama Othman <ossama@uci.edu>
+ */
+//=============================================================================
+
+#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 "Current_TestC.h"
+
+#include "tao/TransportCurrent/TCC.h"
+
+#include "tao/PortableInterceptorC.h"
+#include "tao/LocalObject.h"
+#include "tao/PI_Server/PI_Server.h"
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4250)
+#endif /* _MSC_VER */
+
+#include "ORBInitializer_T.h"
+
+namespace Test
+{
+
+ /// A metod doing the actual testing, so we could change it for the
+ /// different traits implementations
+
+ typedef int (*TEST) (CORBA::ORB_ptr ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+
+ /**
+ * @class Server_Request_Interceptor
+ *
+ * @brief Simple concrete server request interceptor.
+ *
+ */
+ class Server_Request_Interceptor
+ : public virtual PortableInterceptor::ServerRequestInterceptor,
+ public virtual TAO_Local_RefCounted_Object
+ {
+ public:
+
+ /// Constructor.
+ Server_Request_Interceptor (const char*orb_id, TEST test);
+
+ /// Destructor.
+ virtual ~Server_Request_Interceptor (void);
+
+ virtual void test_transport_current (const char* amethod
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual bool self_test (void) const;
+
+ /**
+ * @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 (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual void destroy (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual void receive_request_service_contexts (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest));
+
+ virtual void receive_request (
+ PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest));
+
+ virtual void send_reply (
+ PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual void send_exception (
+ PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest));
+
+ virtual void send_other (
+ PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest));
+ //@}
+
+ protected:
+
+ /// The number of requests intercepted by this interceptor.
+ CORBA::ULong request_count_;
+
+ CORBA::String_var orb_id_;
+
+ TEST test_;
+
+ };
+
+ // A specialization to handle server-side interceptor registration
+ template <>
+ void ORBInitializer<PortableInterceptor::ServerRequestInterceptor>::post_init
+ (PortableInterceptor::ORBInitInfo* oii ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+};
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif /* _MSC_VER */
+
+#endif /* SERVER_REQUEST_INTERCEPTOR_H */
diff --git a/TAO/tests/TransportCurrent/Framework/Tester.cpp b/TAO/tests/TransportCurrent/Framework/Tester.cpp
new file mode 100644
index 00000000000..183691c3f4c
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/Tester.cpp
@@ -0,0 +1,70 @@
+// $Id:$
+
+#include "tao/TransportCurrent/Transport_Current.h"
+
+using namespace TAO;
+
+
+/// Test referencing the TC data outside of the context of an upcall,
+/// or a client-side interceptor
+
+int
+test_transport_current (Transport::Current_ptr tc
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ CORBA::UserException))
+{
+ CORBA::Long id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ TAO::CounterT bs = tc->bytes_sent (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ TAO::CounterT br = tc->bytes_received (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ TAO::CounterT rs = tc->messages_sent (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ TAO::CounterT rr = tc->messages_received (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Tester (%P|%t) Transport [%q] - Sent/Received [bytes=%q/%q, messages=%q/%q]\n"),
+ (ACE_UINT64)id,
+ (ACE_UINT64)bs,
+ (ACE_UINT64)br,
+ (ACE_UINT64)rs,
+ (ACE_UINT64)rr));
+
+ return 0;
+}
+
+int
+test_transport_current (CORBA::ORB_ptr orb
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ CORBA::UserException))
+{
+ // Get the Current object.
+ CORBA::Object_var tcobject =
+ orb->resolve_initial_references ("TAO::Transport::Current"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ Transport::Current_var tc =
+ Transport::Current::_narrow (tcobject.in ()
+ ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (tc.in ()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) client - ERROR: Could not resolve ")
+ ACE_TEXT ("TAOTransportCurrent object.\n")));
+
+ ACE_TRY_THROW (CORBA::INTERNAL ());
+ }
+
+ return test_transport_current (tc.in ());
+}
diff --git a/TAO/tests/TransportCurrent/Framework/client-static.conf b/TAO/tests/TransportCurrent/Framework/client-static.conf
new file mode 100644
index 00000000000..0f63cfe7965
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/client-static.conf
@@ -0,0 +1 @@
+static TAO_Transport_Current_Loader ""
diff --git a/TAO/tests/TransportCurrent/Framework/client.conf b/TAO/tests/TransportCurrent/Framework/client.conf
new file mode 100644
index 00000000000..aecb1923f83
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/client.conf
@@ -0,0 +1 @@
+dynamic TAO_Transport_Current_Loader Service_Object * TAO_TC:_make_TAO_Transport_Current_Loader() ""
diff --git a/TAO/tests/TransportCurrent/Framework/client.cpp b/TAO/tests/TransportCurrent/Framework/client.cpp
new file mode 100644
index 00000000000..db18e0ddc54
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/client.cpp
@@ -0,0 +1,287 @@
+// -*- C++ -*-
+
+#include "ace/Get_Opt.h"
+#include "ace/Task.h"
+
+#include "tao/DynamicInterface/Request.h"
+#include "tao/ORBInitializer_Registry.h"
+
+#include "tao/TransportCurrent/Transport_Current.h"
+
+#include "Client_Request_Interceptor.h"
+#include "Current_TestC.h"
+
+#include "ORBInitializer_T.h"
+
+ACE_RCSID (PICurrent,
+ client,
+ "$Id:$")
+
+// Prototype
+
+int
+test_transport_current (CORBA::ORB_ptr
+ ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException,
+ CORBA::UserException));
+
+using namespace TAO;
+
+const ACE_TCHAR* CLIENT_ORB_ID = ACE_TEXT ("client orb");
+const ACE_TCHAR* ior = "file://server.ior";
+
+int nthreads = 1;
+int niterations = 1;
+int use_dii = 1;
+
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "yt:n:k:");
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'y':
+ use_dii = 0; // Do not use DII
+ break;
+ case 'k':
+ ior = get_opts.opt_arg ();
+ break;
+ case 't':
+ nthreads = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ case 'n':
+ niterations = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Usage: %s "
+ "-k IOR "
+ "-t threads "
+ "-n iterations "
+ "-y "
+ "\n",
+ argv[0]),
+ -1);
+ }
+ return 0;
+}
+
+
+/// A helper class to encapsulate a task
+
+class Worker : public ACE_Task_Base
+{
+public:
+ Worker (TAO::Transport::CurrentTest_ptr server, int niterations, int use_dii_too);
+ virtual int svc (void);
+
+private:
+ // The server.
+ TAO::Transport::CurrentTest_var server_;
+
+ // The number of iterations on each client thread.
+ int niterations_;
+
+ // Whether to use DII in addition to SII
+ int use_dii_too_;
+};
+
+
+/// Ctor
+
+Worker::Worker (TAO::Transport::CurrentTest_ptr server,
+ int niterations,
+ int use_dii_too)
+ : server_ (TAO::Transport::CurrentTest::_duplicate (server))
+ , niterations_ (niterations)
+ , use_dii_too_ (use_dii_too)
+{
+}
+
+
+/// Test referencing the TC data *inside* the context of a client-side
+/// interceptor
+
+int
+Worker::svc (void)
+{
+ ACE_TRY_NEW_ENV
+ {
+
+ for (int i = 0; i < this->niterations_; ++i)
+ {
+
+ if (this->use_dii_too_)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Client (%P|%t) Invoking server->invoked_by_client() via DII\n")));
+
+ CORBA::Request_var request =
+ this->server_->_request ("invoked_by_client"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ request->set_return_type (CORBA::_tc_void);
+
+ request->invoke (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Client (%P|%t) Invoking server->invoked_by_client() via SII\n")));
+
+ this->server_->invoked_by_client (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (TAO_debug_level > 0 && i % 100 == 0)
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Client (%P|%t) Iteration = %d\n"),
+ i));
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Client: exception raised");
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+
+/// The main driver
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ Test::Client_Request_Interceptor cri (CLIENT_ORB_ID, test_transport_current);
+
+ PortableInterceptor::ORBInitializer_ptr temp_initializer =
+ PortableInterceptor::ORBInitializer::_nil ();
+
+ ACE_NEW_RETURN (temp_initializer,
+ Test::ORBInitializer<PortableInterceptor::ClientRequestInterceptor> (&cri),
+ -1);
+
+ PortableInterceptor::ORBInitializer_var orb_initializer =
+ temp_initializer;
+
+ PortableInterceptor::register_orb_initializer (orb_initializer.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc,
+ argv,
+ CLIENT_ORB_ID
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Client (%P|%t) Failure to parse the command line.\n"),
+ ior),
+ -1);
+
+
+ ACE_TRY
+ {
+ test_transport_current (orb.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Client (%P|%t) ERROR: ")
+ ACE_TEXT ("TC invocation, outside of ")
+ ACE_TEXT ("interceptor context is undefined.")
+ ACE_TEXT (" Expected exception was not thrown\n")),
+ -1);
+ }
+ ACE_CATCH (Transport::NoContext, ex)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Client (%P|%t) Expected exception occured when trying ")
+ ACE_TEXT ("to access traits outside the ")
+ ACE_TEXT ("interceptor or upcall context.\n")));
+ }
+ ACE_ENDTRY;
+
+ // Resolve the target object
+ CORBA::Object_var obj = orb->string_to_object (ior ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ Transport::CurrentTest_var server =
+ Transport::CurrentTest::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (server.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Client (%P|%t) The server object reference <%s> is nil.\n"),
+ ior),
+ -1);
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Client (%P|%t) Spawning %d threads\n"), nthreads));
+
+ // Spawn a number of clients doing the same thing for a
+ // predetermined number of times
+ Worker client (server.in (), niterations, use_dii);
+ if (client.activate (THR_NEW_LWP | THR_JOINABLE,
+ nthreads) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Client (%P|%t) Cannot activate the threads\n")),
+ -1);
+ client.thr_mgr ()->wait ();
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Client (%P|%t) Collected all threads\n")));
+
+ CORBA::Long result = 0;
+
+ // Verify enough interception points have been triggered
+ if (cri.interceptions () != 2 * // request & response
+ niterations * // iterations
+ nthreads * // threads
+ (2*use_dii)) // sii and dii, if needed
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Client (%P|%t) Expected %d client-side interceptions, but detected %d\n"),
+ 2 * niterations * nthreads * (2*use_dii),
+ cri.interceptions ()));
+ }
+ else
+ {
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Client (%P|%t) Invoking server->self_test()\n")));
+
+ // Self-test the server side
+ result = server->self_test (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (result != 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Client (%P|%t) Server self-test reported failure\n")));
+ }
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Client (%P|%t) Invoking oneway server->shutdown()\n")));
+
+ server->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Client (%P|%t) Completed %s\n"),
+ ((result == 0) ? ACE_TEXT ("successfuly") : ACE_TEXT ("with failure"))));
+ return result;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ ACE_TEXT ("Client: Transport Current test (client-side) failed:"));
+ return -1;
+ }
+ ACE_ENDTRY;
+}
diff --git a/TAO/tests/TransportCurrent/Framework/run_test.pl b/TAO/tests/TransportCurrent/Framework/run_test.pl
new file mode 100755
index 00000000000..2f50e0f7609
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/run_test.pl
@@ -0,0 +1,59 @@
+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;
+
+$status = 0;
+
+#$confmod = "-static";
+
+$iorfile = PerlACE::LocalFile ("server.ior");
+$confserver = PerlACE::LocalFile ("server$confmod.conf");
+$confclient = PerlACE::LocalFile ("client$confmod.conf");
+unlink $iorfile;
+
+if (PerlACE::is_vxworks_test()) {
+ $SV = new PerlACE::ProcessVX ("server",
+ "@ARGV -ORBSvcConf server.conf -o server.ior");
+}
+else {
+ $SV = new PerlACE::Process ("server",
+ "@ARGV -ORBSvcConf $confserver -o $iorfile");
+}
+
+$CL = new PerlACE::Process ("client",
+ "@ARGV -n 1 -ORBSvcConf $confclient -k file://$iorfile");
+
+print STDERR $SV->CommandLine()."\n";
+$SV->Spawn ();
+
+if (PerlACE::waitforfile_timed ($iorfile,
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "$0: ERROR: cannot find file <$iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+print STDERR $CL->CommandLine()."\n";
+$client = $CL->SpawnWaitKill (300);
+
+if ($client != 0) {
+ print STDERR "$0: ERROR: client returned $client\n";
+ $status = 1;
+}
+
+$server = $SV->WaitKill (10);
+
+if ($server != 0) {
+ print STDERR "$0: ERROR: server returned $server\n";
+ $status = 1;
+}
+
+unlink $iorfile;
+
+exit $status;
diff --git a/TAO/tests/TransportCurrent/Framework/server-static.conf b/TAO/tests/TransportCurrent/Framework/server-static.conf
new file mode 100644
index 00000000000..0f63cfe7965
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/server-static.conf
@@ -0,0 +1 @@
+static TAO_Transport_Current_Loader ""
diff --git a/TAO/tests/TransportCurrent/Framework/server.conf b/TAO/tests/TransportCurrent/Framework/server.conf
new file mode 100644
index 00000000000..aecb1923f83
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/server.conf
@@ -0,0 +1 @@
+dynamic TAO_Transport_Current_Loader Service_Object * TAO_TC:_make_TAO_Transport_Current_Loader() ""
diff --git a/TAO/tests/TransportCurrent/Framework/server.cpp b/TAO/tests/TransportCurrent/Framework/server.cpp
new file mode 100644
index 00000000000..93bfcae4ac0
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/server.cpp
@@ -0,0 +1,240 @@
+// -*- C++ -*-
+
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/Task.h"
+
+#include "tao/ORBInitializer_Registry.h"
+
+#include "Current_Test_Impl.h"
+#include "Server_Request_Interceptor.h"
+
+ACE_RCSID (Transport_Current,
+ server,
+ "$Id$")
+
+#if defined (TAO_AS_STATIC_LIBS)
+
+// Create an object that will insert the <Current_Loader> into the
+// list of statically linked services that the <ACE_Service_Config>
+// will initialize at run-time.
+#include "orbsvcs/Transport_Current/Current_Loader.h"
+ACE_STATIC_SVC_REQUIRE (TAO_Transport_Current_Loader);
+#endif
+
+const char *ior_output_file = "server.ior";
+int nthreads = 1;
+int use_collocated_call = 1;
+
+int
+parse_args (int argc, char *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "t:o:n:c:");
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'c':
+ use_collocated_call = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ case 'o':
+ ior_output_file = get_opts.opt_arg ();
+ break;
+ case 't':
+ nthreads = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ case 'n': // Does nothing. Added just for symetry with the client.
+ break;
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Usage: %s "
+ "-o <iorfile>"
+ "-t threads "
+ "-n n (ignored, if provided) "
+ "-c make_collocated_calls "
+ "\n",
+ argv[0]),
+ -1);
+ }
+
+ // Indicates sucessful parsing of the command line
+ return 0;
+}
+
+
+
+/// A helper class to encapsulate a task
+
+class Worker : public ACE_Task_Base
+{
+public:
+ Worker (CORBA::ORB_ptr);
+ virtual int svc (void);
+
+private:
+ // The ORB
+ CORBA::ORB_var orb_;
+};
+
+
+/// Ctor
+
+Worker::Worker (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb))
+{
+}
+
+
+/// Test referencing the TC data *inside* the context of a client-side
+/// interceptor
+
+int
+Worker::svc (void)
+{
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Server: exception raised");
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+
+
+/// Main driver
+
+int
+server_main (int argc,
+ ACE_TCHAR *argv[],
+ Test::Server_Request_Interceptor *cri)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ PortableInterceptor::ORBInitializer_ptr temp_initializer =
+ PortableInterceptor::ORBInitializer::_nil ();
+
+ ACE_NEW_RETURN (temp_initializer,
+ Test::ORBInitializer <PortableInterceptor::ServerRequestInterceptor> (cri),
+ -1); // No exceptions yet!
+
+ PortableInterceptor::ORBInitializer_var orb_initializer =
+ temp_initializer;
+
+ PortableInterceptor::register_orb_initializer (orb_initializer.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ CORBA::ORB_var orb = CORBA::ORB_init (argc,
+ argv,
+ ACE_TEXT ("test_orb")
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::Object_var obj =
+ orb->resolve_initial_references ("RootPOA"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (obj.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (root_poa.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Server (%P|%t) Unable to obtain")
+ ACE_TEXT (" RootPOA reference.\n")),
+ -1);
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) != 0)
+ return -1;
+
+ Current_Test_Impl server_impl (orb.in (),
+ root_poa.in (),
+ use_collocated_call);
+
+ obj = server_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ TAO::Transport::CurrentTest_var server =
+ TAO::Transport::CurrentTest::_narrow (obj.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (server.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Server (%P|%t) Unable to obtain ")
+ ACE_TEXT ("reference to CurrentTest object.\n")),
+ -1);
+
+ CORBA::String_var ior =
+ orb->object_to_string (server.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // 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,
+ "Server (%P|%t) Cannot write "
+ "IOR: %s - %m",
+ ior_output_file),
+ -1);
+ ACE_OS::fprintf (output_file, "%s", ior.in ());
+ ACE_OS::fclose (output_file);
+ }
+
+ // Spawn a number of clients doing the same thing for a
+ // predetermined number of times
+ Worker worker (orb.in ());
+ if (worker.activate (THR_NEW_LWP | THR_JOINABLE,
+ nthreads) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Server (%P|%t) Cannot activate %d server threads\n"),
+ nthreads),
+ -1);
+ worker.thr_mgr ()->wait ();
+
+ if (TAO_debug_level >= 1)
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("Server (%P|%t) Event loop finished.\n")));
+
+ if (!cri->self_test ())
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Server (%P|%t) Interceptor self_test failed\n")));
+
+ server->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ ACE_TEXT ("Server (%P|%t) ERROR: "));
+
+ return -1;
+ }
+ ACE_ENDTRY;
+
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("Server (%P|%t) Completed successfuly.\n")));
+ return 0;
+}
diff --git a/TAO/tests/TransportCurrent/Framework/simple.cpp b/TAO/tests/TransportCurrent/Framework/simple.cpp
new file mode 100644
index 00000000000..d301278536d
--- /dev/null
+++ b/TAO/tests/TransportCurrent/Framework/simple.cpp
@@ -0,0 +1,86 @@
+// -*- C++ -*-
+
+#include "tao/ORB.h"
+#include "tao/Object.h"
+
+#include "ace/Service_Config.h"
+#include "ace/Dynamic_Service.h"
+
+ACE_RCSID (Transport_Current,
+ simple,
+ "$Id$")
+
+int
+testCurrentORBInitializer (int argc, char *argv[])
+{
+ CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
+
+ if (orb.in () == 0)
+ ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Unable to create orb\n")), -1);
+
+ CORBA::Object_var obj =
+ orb->resolve_initial_references ("TAO::Transport::Current"
+ ACE_ENV_ARG_PARAMETER);
+
+ if (obj.in () == 0)
+ ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Unable to get the Transport Current\n")), -1);
+
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("testCurrentORBInitializer: OK\n")));
+ return 0;
+}
+
+
+int
+testCurrentLoader (int, char *[])
+{
+
+ ACE_Service_Object *factory = 0;
+
+ factory = ACE_Dynamic_Service<ACE_Service_Object>::instance
+ (ACE_TEXT ("TAO_Transport_Current_Loader"));
+
+ int done =
+#if defined (TAO_AS_STATIC_LIBS)
+ true;
+#else
+ (factory != 0);
+#endif /* TAO_AS_STATIC_LIBS */
+
+ if (factory == 0)
+ {
+ if (done)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unable to instantiate TAO::Transport::Current_Factory\n")),
+ -1);
+ else
+ {
+
+#if !defined (TAO_AS_STATIC_LIBS)
+ int ret = ACE_Service_Config::process_directive
+ (ACE_DYNAMIC_SERVICE_DIRECTIVE("TAO_Transport_Current_Loader",
+ "TAO_Transport_Current",
+ "_make_TAO_Transport_Current_Loader",
+ ""));
+ ACE_ASSERT (ret == 0);
+
+ factory = ACE_Dynamic_Service<ACE_Service_Object>::instance
+ (ACE_TEXT ("TAO_Transport_Current_Loader"));
+
+#endif /* !TAO_AS_STATIC_LIBS */
+ }
+ }
+
+ // ACE_ASSERT (factory != 0);
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("testCurrentLoader: OK\n")));
+ return 0;
+
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ return testCurrentLoader (argc, argv)
+ || testCurrentORBInitializer (argc, argv);
+}
diff --git a/TAO/tests/TransportCurrent/IIOP/Current_Test_Impl.cpp b/TAO/tests/TransportCurrent/IIOP/Current_Test_Impl.cpp
new file mode 100644
index 00000000000..1001d1ea528
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/Current_Test_Impl.cpp
@@ -0,0 +1,139 @@
+// -*- C++ -*-
+
+#include "Current_Test_Impl.h"
+
+#include "orbsvcs/Transport_Current/TC_IIOPC.h"
+#include "orbsvcs/Transport_Current/TCC.h"
+
+ACE_RCSID (Transport_Current,
+ Current_Test_Impl,
+ "$Id:$")
+
+
+Current_Test_Impl::Current_Test_Impl (CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ int do_collocated_calls)
+ : orb_ (CORBA::ORB::_duplicate (orb))
+ , poa_ (PortableServer::POA::_duplicate (poa))
+ , do_collocated_calls_ (do_collocated_calls)
+{
+}
+
+Current_Test_Impl::~Current_Test_Impl (void)
+{
+}
+
+::CORBA::Long
+Current_Test_Impl::self_test (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((::CORBA::SystemException))
+{
+ return 0;
+}
+
+void
+Current_Test_Impl::test_transport_current (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (TAO_debug_level > 2) {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - Testing access to IIOP Transport Current ...\n")));
+ }
+
+ CORBA::Object_var tcobject =
+ this->orb_->resolve_initial_references ("TAO::Transport::IIOP::Current"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ TAO::Transport::IIOP::Current_var tc =
+ TAO::Transport::IIOP::Current::_narrow (tcobject.in ()
+ ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (tc.in()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Unable to narrow down to TAO::Transport::IIOP::Current\n")));
+ ACE_THROW (CORBA::INTERNAL ());
+ }
+
+ CORBA::String_var rhost (tc->remote_host ());
+ CORBA::String_var lhost (tc->local_host ());
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - [%s:%d] -> [%s:%d]\n"),
+ rhost.in (), tc->remote_port (),
+ lhost.in (), tc->local_port ()));
+
+ if (TAO_debug_level > 2) {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - Successfully accessed IIOP Transport Current\n")));
+ }
+}
+
+
+
+void
+Current_Test_Impl::invoked_by_client (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (TAO_debug_level >= 1) {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - Test method invoked by client.\n")));
+ }
+
+ this->test_transport_current (ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ if (this->do_collocated_calls_)
+ {
+ CORBA::Object_var selfobject =
+ poa_->servant_to_reference (this
+ ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ TAO::Transport::CurrentTest_var self =
+ TAO::Transport::CurrentTest::_narrow (selfobject.in ()
+ ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ if (TAO_debug_level >= 1) {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - Making a collocated invocation to invoked_during_upcall().\n")));
+ }
+ self->invoked_during_upcall (ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ else
+ {
+ if (TAO_debug_level >= 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - skipping collocated calls\n")));
+ }
+
+ }
+
+}
+
+void
+Current_Test_Impl::invoked_during_upcall (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (TAO_debug_level > 2) {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - Test method invoked ")
+ ACE_TEXT ("by the server during upcall.\n")));
+ }
+}
+
+void
+Current_Test_Impl::shutdown (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (TAO_debug_level > 2) {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - shutting down.\n")));
+ }
+
+ this->orb_->shutdown (0
+ ACE_ENV_ARG_PARAMETER);
+}
diff --git a/TAO/tests/TransportCurrent/IIOP/IIOP.mpc b/TAO/tests/TransportCurrent/IIOP/IIOP.mpc
new file mode 100644
index 00000000000..ea9d41d5b07
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/IIOP.mpc
@@ -0,0 +1,42 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): taoserver, tc, pi_server {
+
+ idlflags += -o ../Framework
+
+ libs += TAO_TC_IIOP
+ includes += ../Framework
+
+ Source_Files {
+ ../Framework/server.cpp
+ ../Framework/Server_Request_Interceptor.cpp
+ Current_Test_Impl.cpp
+ IIOP_Server_Request_Interceptor.cpp
+ IIOP_Server_Main.cpp
+ IIOP_Tester.cpp
+ }
+
+ IDL_Files {
+ ../Framework/Current_Test.idl
+ }
+}
+
+project(*Client): taoclient, tc, pi, dynamicinterface {
+
+ after += *Server*
+
+ includes += ../Framework
+ libs += TAO_TC_IIOP
+
+ idlflags += -o ../Framework
+
+ Source_Files {
+ ../Framework/Client_Request_Interceptor.cpp
+ ../Framework/client.cpp
+ IIOP_Tester.cpp
+ }
+ IDL_Files {
+ ../Framework/Current_Test.idl
+ }
+}
diff --git a/TAO/tests/TransportCurrent/IIOP/IIOP_Server_Main.cpp b/TAO/tests/TransportCurrent/IIOP/IIOP_Server_Main.cpp
new file mode 100644
index 00000000000..cce444d8662
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/IIOP_Server_Main.cpp
@@ -0,0 +1,23 @@
+// -*- C++ -*-
+
+// $Id$
+
+#include "IIOP_Server_Request_Interceptor.h"
+
+/// Prototype
+int server_main (int argc,
+ ACE_TCHAR *argv[],
+ Test::Server_Request_Interceptor *cri);
+
+int
+test_transport_current (CORBA::ORB_ptr orb
+ ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException,
+ CORBA::UserException));
+
+int
+ACE_TMAIN (int argc,
+ ACE_TCHAR *argv[])
+{
+ Test::IIOP_Server_Request_Interceptor cri ("test_orb", test_transport_current);
+ return server_main (argc, argv, &cri);
+}
diff --git a/TAO/tests/TransportCurrent/IIOP/IIOP_Server_Request_Interceptor.cpp b/TAO/tests/TransportCurrent/IIOP/IIOP_Server_Request_Interceptor.cpp
new file mode 100644
index 00000000000..1dbf33e8cfe
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/IIOP_Server_Request_Interceptor.cpp
@@ -0,0 +1,323 @@
+// -*- C++ -*-
+
+#include "ace/Log_Msg.h"
+#include "tao/ORB_Constants.h"
+#include "tao/TransportCurrent/TC_IIOPC.h"
+
+ACE_RCSID (ForwardRequest,
+ Server_Request_Interceptor,
+ "$Id$")
+
+#include "IIOP_Server_Request_Interceptor.h"
+
+namespace Test {
+
+ using namespace TAO;
+
+ IIOP_Server_Request_Interceptor::IIOP_Server_Request_Interceptor (const char* orbid, TEST test)
+ : Server_Request_Interceptor (orbid, test)
+ , iiop_test_successful_ (true)
+ , mult_thr_test_successful_ (true)
+ {
+ }
+
+ IIOP_Server_Request_Interceptor::~IIOP_Server_Request_Interceptor (void)
+ {
+ }
+
+ char *
+ IIOP_Server_Request_Interceptor::name (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ return CORBA::string_dup ("II SRI");
+ }
+
+ ///
+ TAO::Transport::IIOP::Current_ptr
+ IIOP_Server_Request_Interceptor::resolve_iiop_transport_current (const char* orbid
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ CORBA::String_var name (this->name ());
+
+ int tmpargc = 0;
+ CORBA::ORB_var orb = CORBA::ORB_init (tmpargc,
+ 0,
+ orbid
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ CORBA::Object_var tcobject =
+ orb->resolve_initial_references (ACE_TEXT_ALWAYS_CHAR ("TAO::Transport::IIOP::Current")
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ return TAO::Transport::IIOP::Current::_narrow (tcobject.in ()
+ ACE_ENV_ARG_PARAMETER);
+ }
+
+ /// On every request, a client-supplied (via the context) id is used
+ /// as index in an array, where we store the endpoint
+ void
+ IIOP_Server_Request_Interceptor::push_request_info (size_t requestID
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ CORBA::String_var name (this->name ());
+
+ TAO::Transport::IIOP::Current_var tc =
+ resolve_iiop_transport_current (this->orb_id_.in ()
+ ACE_ENV_ARG_PARAMETER);
+
+ CORBA::String_var host (tc->remote_host());
+ EndPoint ep (tc->remote_port(), host.in ());
+
+ if (requestID < sizeof (endPoints_))
+ endPoints_[requestID] = ep;
+ else
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%s (%P|%t) ")
+ ACE_TEXT ("push_request_info: Can't track that many requests %d\n"),
+ name.in (),
+ requestID));
+
+ }
+
+ void
+ IIOP_Server_Request_Interceptor::pop_request_info (size_t requestID)
+ {
+ static EndPoint dummy;
+ CORBA::String_var name (this->name ());
+
+ if (requestID >= sizeof (endPoints_))
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%s (%P|%t) ")
+ ACE_TEXT ("pop_request_info: Can't track that many requests %d\n"),
+ name.in (),
+ requestID));
+ return;
+ }
+
+ TAO::Transport::IIOP::Current_var tc =
+ resolve_iiop_transport_current (this->orb_id_.in ()
+ ACE_ENV_ARG_PARAMETER);
+
+ CORBA::String_var host (tc->remote_host());
+ EndPoint ep (tc->remote_port(), host.in ());
+
+ if (ep != endPoints_[requestID])
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%s (%P|%t) ")
+ ACE_TEXT ("pop_request_info: The expected host and port don't match for request %d\n"),
+ name.in (),
+ requestID));
+ return;
+ }
+
+ endPoints_[requestID] = dummy;
+ }
+
+
+ /// Checks if all the endpoints, encountered on the way in have been
+ /// cleaned on the way out of the interception point
+ bool
+ IIOP_Server_Request_Interceptor::self_test (void)
+ {
+ CORBA::String_var name (this->name ());
+ bool has_remaining_endpoints = false;
+ for (size_t count = 0;
+ count < sizeof (endPoints_);
+ count ++)
+ {
+ if (endPoints_[count].port_ != 0)
+ {
+ has_remaining_endpoints = true;
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%s (%S|%t) Endpoint at ")
+ ACE_TEXT ("index=%d is not been removed yet\n"),
+ name.in ()));
+ }
+ }
+
+ return Server_Request_Interceptor::self_test ()
+ && iiop_test_successful_
+ && !has_remaining_endpoints;
+ }
+
+
+
+ void
+ IIOP_Server_Request_Interceptor::inbound_process_context (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ CORBA::String_var name (this->name ());
+ CORBA::String_var op (ri->operation(ACE_ENV_ARG_PARAMETER));
+ ACE_CHECK;
+
+ if (TAO_debug_level >=1)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("%s (%P|%t) Intercepted operation %s ()\n"),
+ name.in (),
+ op.in ()));
+
+ ACE_TRY
+ {
+ IOP::ServiceId id = Transport::CurrentTest::ContextTag;
+ IOP::ServiceContext_var sc =
+ ri->get_request_service_context (id
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ const char *buf =
+ ACE_reinterpret_cast (const char *, sc->context_data.get_buffer ());
+
+ long requestID = ACE_OS::atoi (buf);
+
+ this->push_request_info (requestID);
+ }
+ ACE_CATCHANY
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%s (%P|%t) Service context")
+ ACE_TEXT (" is unavailable when invoking %s (). ")
+ ACE_TEXT ("A colocated invocation would have ")
+ ACE_TEXT ("no service context.\n"),
+ name.in (),
+ op.in ()));
+ }
+ ACE_ENDTRY;
+
+ }
+
+ void
+ IIOP_Server_Request_Interceptor::outbound_process_context (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ IOP::ServiceId id = Transport::CurrentTest::ContextTag;
+
+ IOP::ServiceContext_var sc =
+ ri->get_request_service_context (id ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ const char *buf =
+ ACE_reinterpret_cast (const char *, sc->context_data.get_buffer ());
+
+ this->pop_request_info (ACE_OS::atoi (buf));
+ }
+
+
+
+
+
+
+ void
+ IIOP_Server_Request_Interceptor::receive_request_service_contexts (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest))
+ {
+ ACE_TRY
+ {
+ inbound_process_context (ri ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ CORBA::String_var name (this->name ());
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT("%s (%P|%t) Inbound_process_context failed in ")
+ ACE_TEXT(" receive_request_service_contexts.\n"),
+ name.in ()));
+ }
+ ACE_ENDTRY;
+
+ Server_Request_Interceptor::receive_request_service_contexts (ri ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ }
+
+
+ void
+ IIOP_Server_Request_Interceptor::send_reply (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+ {
+ ACE_TRY
+ {
+ outbound_process_context (ri ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ }
+ ACE_CATCHANY
+ {
+ CORBA::String_var name (this->name ());
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT("%s (%P|%t) Outbound_process_context failed in ")
+ ACE_TEXT("send_reply.\n"),
+ name.in ()));
+ }
+ ACE_ENDTRY;
+
+ Server_Request_Interceptor::send_reply (ri ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ }
+
+ void
+ IIOP_Server_Request_Interceptor::send_exception (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest))
+ {
+ ACE_TRY
+ {
+ outbound_process_context (ri ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ }
+ ACE_CATCHANY
+ {
+ CORBA::String_var name (this->name ());
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT("%s (%P|%t) Outbound_process_context failed in ")
+ ACE_TEXT("send_exception.\n"),
+ name.in ()));
+
+ }
+ ACE_ENDTRY;
+
+ Server_Request_Interceptor::send_exception (ri ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ void
+ IIOP_Server_Request_Interceptor::send_other (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest))
+ {
+ ACE_TRY
+ {
+ outbound_process_context (ri ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ CORBA::String_var name (this->name ());
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT("%s (%P|%t) Outbound_process_context failed in ")
+ ACE_TEXT("send_other.\n"),
+ name.in ()));
+ }
+ ACE_ENDTRY;
+
+ Server_Request_Interceptor::send_other (ri ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+}
diff --git a/TAO/tests/TransportCurrent/IIOP/IIOP_Server_Request_Interceptor.h b/TAO/tests/TransportCurrent/IIOP/IIOP_Server_Request_Interceptor.h
new file mode 100644
index 00000000000..914b51b4bb1
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/IIOP_Server_Request_Interceptor.h
@@ -0,0 +1,162 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file IIOP_Server_Request_Interceptor.h
+ *
+ * $Id$
+ *
+ * Implementation header for the server request interceptor for the
+ * IIOP_Threading test.
+ *
+ * @author Iliyan Jeliazkov <iliyan@ociweb.com>
+ * @author Ciju John <johnc@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ISERVER_REQUEST_INTERCEPTOR_H
+#define ISERVER_REQUEST_INTERCEPTOR_H
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "Server_Request_Interceptor.h"
+#include "tao/TransportCurrent/IIOP_Transport_Current.h"
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4250)
+#endif /* _MSC_VER */
+
+namespace Test
+{
+
+ class IIOP_Server_Request_Interceptor
+ : public virtual Test::Server_Request_Interceptor
+ , public virtual TAO_Local_RefCounted_Object
+ {
+ public:
+
+ /// Constructor.
+ IIOP_Server_Request_Interceptor (const char* orbid, TEST test);
+
+ /// Destructor.
+ virtual ~IIOP_Server_Request_Interceptor ();
+
+ /// queries the status of the test
+ bool self_test ();
+
+ /**
+ * @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 (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// incomming interception point
+ virtual void receive_request_service_contexts (PortableInterceptor::ServerRequestInfo_ptr
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest));
+
+ /// outgoing interception point
+ virtual void send_reply (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// outgoing interception point
+ virtual void send_exception (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest));
+
+ /// outgoing interception point
+ virtual void send_other (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest));
+ //@}
+
+ protected:
+
+ /// process incomming requests context
+ void inbound_process_context
+ (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// process outgoing requests context
+ void outbound_process_context
+ (PortableInterceptor::ServerRequestInfo_ptr ri
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// saves the incomming request info
+ void push_request_info (size_t requestID
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// clears the outgoing request info
+ void pop_request_info (size_t requestID);
+
+ TAO::Transport::IIOP::Current_ptr resolve_iiop_transport_current (const char* orbid
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ private:
+
+ /// transport ID dtata structure
+ typedef struct EP {
+ CORBA::UShort port_;
+ CORBA::String_var host_;
+
+ EP ()
+ : port_(0)
+ , host_ ()
+ {};
+
+ EP (CORBA::UShort port, const char* host)
+ : port_(port)
+ , host_ (host)
+ {};
+
+ bool operator== (const struct EP &ep) const
+ {
+ return (this->port_ == ep.port_) &&
+ (strcmp (this->host_.in (), ep.host_.in ()) == 0);
+ };
+ bool operator!= (const struct EP &ep) const
+ {
+ return !(this->operator== (ep));
+ };
+
+ } EndPoint;
+
+ private:
+
+ /// IIOPTraits test status
+ bool iiop_test_successful_;
+
+ /// Multi-threaded test status
+ bool mult_thr_test_successful_;
+
+ /// Endpoints hash table
+ EndPoint endPoints_[1001];
+ };
+
+}; /* namespace Test */
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif /* _MSC_VER */
+
+#endif /* ISERVER_REQUEST_INTERCEPTOR_H */
diff --git a/TAO/tests/TransportCurrent/IIOP/IIOP_Tester.cpp b/TAO/tests/TransportCurrent/IIOP/IIOP_Tester.cpp
new file mode 100644
index 00000000000..24f0a23937c
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/IIOP_Tester.cpp
@@ -0,0 +1,81 @@
+// -*- C++ -*-
+
+// $Id$
+
+#include "tao/TransportCurrent/IIOP_Transport_Current.h"
+
+using namespace TAO;
+
+
+/// Test referencing the TC data outside of the context of an upcall,
+/// or a client-side interceptor
+
+int
+test_transport_current (CORBA::ORB_ptr orb
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ CORBA::UserException))
+{
+ // Get the Current object.
+ CORBA::Object_var tcobject =
+ orb->resolve_initial_references (ACE_TEXT_ALWAYS_CHAR ("TAO::Transport::IIOP::Current")
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ if (TAO_debug_level >= 1)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Tester (%P|%t) Resolved initial reference for IIOP::Current\n")));
+
+ Transport::IIOP::Current_var tc =
+ Transport::IIOP::Current::_narrow (tcobject.in ()
+ ACE_ENV_SINGLE_ARG_DECL);
+ ACE_TRY_CHECK;
+
+ if (TAO_debug_level >= 1)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Tester (%P|%t) Narowed the IIOP Transport Current\n")));
+
+ if (CORBA::is_nil (tc.in ()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Tester (%P|%t) ERROR: Could not resolve ")
+ ACE_TEXT ("TAO::Transport::IIOP::Current object.\n")));
+
+ ACE_TRY_THROW (CORBA::INTERNAL ());
+ }
+
+ ::CORBA::String_var rhost (tc->remote_host (ACE_ENV_SINGLE_ARG_PARAMETER));
+ ACE_TRY_CHECK;
+
+ ::CORBA::String_var lhost (tc->local_host (ACE_ENV_SINGLE_ARG_PARAMETER));
+ ACE_TRY_CHECK;
+
+ ::CORBA::Long id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT bs = tc->bytes_sent (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT br = tc->bytes_received (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT rs = tc->messages_sent (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ::TAO::CounterT rr = tc->messages_received (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Tester (%P|%t) Transport [%q] [%s:%d -> %s:%d] ")
+ ACE_TEXT ("Sent/Received [bytes=%q/%q, messages=%q/%q]\n"),
+ (ACE_UINT64)id,
+ rhost.in (), tc->remote_port (ACE_ENV_SINGLE_ARG_PARAMETER),
+ lhost.in (), tc->local_port (ACE_ENV_SINGLE_ARG_PARAMETER),
+ (ACE_UINT64)bs,
+ (ACE_UINT64)br,
+ (ACE_UINT64)rs,
+ (ACE_UINT64)rr));
+ return 0;
+}
+
diff --git a/TAO/tests/TransportCurrent/IIOP/README b/TAO/tests/TransportCurrent/IIOP/README
new file mode 100644
index 00000000000..b340cfcab02
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/README
@@ -0,0 +1,25 @@
+This test has two parts, which run automatically:
+
+Part 1:
+
+IIOP_Transport_Current test: Demonstrates how in the application the
+user can resolve the IIOP_Transport_Current and use it to obtain
+IIOP-related transport properties for the current Transport.
+
+Part 2:
+
+Multi threading test: In this test the server has a Thread Pool. Using
+Interceptors, the test tracks the transports that are used in the
+individual invocations at various stage of the up-call. This validates
+that the TC framework accurately tracks the correct transport for an
+invocation, no matter what stage of the up-call in a multi-threaded
+environment.
+
+We force creation of multiple transport by using the: static
+Client_Strategy_Factory "-ORBTransportMuxStrategy exclusive"
+directive. While this isn't 100% guaranteed, having multiple client
+threads and making simultaneous invocations should trigger new transport
+creation (as it did in lab conditions).
+
+See ../Framework/README for more detail on how and what contexts are
+tested.
diff --git a/TAO/tests/TransportCurrent/IIOP/client_dynamic.conf b/TAO/tests/TransportCurrent/IIOP/client_dynamic.conf
new file mode 100644
index 00000000000..56ff8d9c269
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/client_dynamic.conf
@@ -0,0 +1,3 @@
+static Client_Strategy_Factory "-ORBTransportMuxStrategy exclusive"
+dynamic TAO_Transport_Current_Loader Service_Object * TAO_TC:_make_TAO_Transport_Current_Loader() ""
+dynamic TAO_Transport_IIOP_Current_Loader Service_Object * TAO_TC_IIOP:_make_TAO_Transport_IIOP_Current_Loader() ""
diff --git a/TAO/tests/TransportCurrent/IIOP/client_static.conf b/TAO/tests/TransportCurrent/IIOP/client_static.conf
new file mode 100644
index 00000000000..42fd412dfca
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/client_static.conf
@@ -0,0 +1,3 @@
+#static TAO_Transport_Current_Loader ""
+#static TAO_Transport_IIOP_Current_Loader ""
+static Client_Strategy_Factory "-ORBTransportMuxStrategy exclusive"
diff --git a/TAO/tests/TransportCurrent/IIOP/run_test.pl b/TAO/tests/TransportCurrent/IIOP/run_test.pl
new file mode 100755
index 00000000000..5daa7f993e2
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/run_test.pl
@@ -0,0 +1,71 @@
+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;
+
+$status = 0;
+
+$client = PerlACE::LocalFile ("client");
+
+$mode = shift (@ARGV);
+if ( $mode =~ /-dynamic/) {
+ $client_conf_file = PerlACE::LocalFile ("client_dynamic.conf");
+ $server_conf_file = PerlACE::LocalFile ("server_dynamic.conf");
+}
+elsif ( $mode =~ /-static/) {
+ $client_conf_file = PerlACE::LocalFile ("client_static.conf");
+ $server_conf_file = PerlACE::LocalFile ("server_static.conf");
+}
+else {
+ print STDERR "Unknown $mode. Specify -static or -dynamic\n";
+ exit 1;
+}
+
+$iorfile = PerlACE::LocalFile ("server.ior");
+unlink $iorfile;
+
+if (PerlACE::is_vxworks_test()) {
+ $SV = new PerlACE::ProcessVX ("server",
+ "@ARGV -c 0 -ORBSvcConf $server_conf_file -o server.ior");
+}
+else {
+ $SV = new PerlACE::Process ("server",
+ "@ARGV -c 0 -ORBSvcConf $server_conf_file -o $iorfile");
+}
+
+$CL = new PerlACE::Process ($client,
+ "@ARGV -n 1 -ORBSvcConf $client_conf_file -k file://$iorfile");
+
+print STDERR $SV->CommandLine()."\n";
+$SV->Spawn ();
+
+if (PerlACE::waitforfile_timed ($iorfile,
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "$0: ERROR: cannot find file <$iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+print STDERR $CL->CommandLine()."\n";
+$client = $CL->SpawnWaitKill (300);
+
+if ($client != 0) {
+ print STDERR "$0: ERROR: client returned $client\n";
+ $status = 1;
+}
+
+$server = $SV->WaitKill (10);
+
+if ($server != 0) {
+ print STDERR "$0: ERROR: server returned $server\n";
+ $status = 1;
+}
+
+unlink $iorfile;
+
+exit $status;
diff --git a/TAO/tests/TransportCurrent/IIOP/server_dynamic.conf b/TAO/tests/TransportCurrent/IIOP/server_dynamic.conf
new file mode 100644
index 00000000000..df5758abd32
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/server_dynamic.conf
@@ -0,0 +1,2 @@
+dynamic TAO_Transport_Current_Loader Service_Object * TAO_TC:_make_TAO_Transport_Current_Loader() ""
+dynamic TAO_Transport_IIOP_Current_Loader Service_Object * TAO_TC_IIOP:_make_TAO_Transport_IIOP_Current_Loader() ""
diff --git a/TAO/tests/TransportCurrent/IIOP/server_static.conf b/TAO/tests/TransportCurrent/IIOP/server_static.conf
new file mode 100644
index 00000000000..a3bca724d53
--- /dev/null
+++ b/TAO/tests/TransportCurrent/IIOP/server_static.conf
@@ -0,0 +1,2 @@
+static TAO_Transport_Current_Loader ""
+static TAO_Transport_IIOP_Current_Loader ""