summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOssama Othman <ossama-othman@users.noreply.github.com>2001-04-10 17:54:40 +0000
committerOssama Othman <ossama-othman@users.noreply.github.com>2001-04-10 17:54:40 +0000
commita82053be75cbe912a4598d758e54f3b6a4151016 (patch)
tree24e362138dc1a19d5450a0d3fc825d4490c45a7b
parentc63e6e2c037356b62da60821d57bffee4b7bde91 (diff)
downloadATCD-a82053be75cbe912a4598d758e54f3b6a4151016.tar.gz
ChangeLogTag:Tue Apr 10 10:45:26 2001 Ossama Othman <ossama@uci.edu>
-rw-r--r--TAO/ChangeLogs/ChangeLog-02a118
-rw-r--r--TAO/tao/Asynch_Invocation.cpp35
-rw-r--r--TAO/tao/Asynch_Invocation.h56
-rw-r--r--TAO/tao/ClientRequestInfo.cpp2
-rw-r--r--TAO/tao/ClientRequestInfo.h2
-rw-r--r--TAO/tao/IIOP_Transport.cpp93
-rw-r--r--TAO/tao/Invocation.cpp67
-rw-r--r--TAO/tao/Invocation.h35
-rw-r--r--TAO/tao/Invocation.i2
-rw-r--r--TAO/tao/PortableInterceptor.cpp315
-rw-r--r--TAO/tao/PortableInterceptor.h13
-rw-r--r--TAO/tao/PortableInterceptor.i266
-rw-r--r--TAO/tao/PortableServer/ServerRequestInfo.cpp37
-rw-r--r--TAO/tao/PortableServer/ServerRequestInfo.h10
-rw-r--r--TAO/tao/Sequence.i34
-rw-r--r--TAO/tao/operation_details.h34
-rw-r--r--TAO/tao/operation_details.i39
17 files changed, 760 insertions, 398 deletions
diff --git a/TAO/ChangeLogs/ChangeLog-02a b/TAO/ChangeLogs/ChangeLog-02a
index 64320f17dd5..e17e019a787 100644
--- a/TAO/ChangeLogs/ChangeLog-02a
+++ b/TAO/ChangeLogs/ChangeLog-02a
@@ -1,3 +1,121 @@
+Tue Apr 10 10:45:26 2001 Ossama Othman <ossama@uci.edu>
+
+ * tao/PortableInterceptor.i (send_request, receive_reply,
+ receive_other, receive_exception,
+ receive_request_service_contexts, receive_request, send_reply,
+ send_other, send_exception):
+
+ Moved these interception points to the
+ `PortableInterceptor.cpp'. They were too big to be inlined, so
+ there was no point in leaving them in this inline source file.
+
+ (receive_exception, send_exception):
+
+ Fixed problem where the remaining interceptors in the flow stack
+ were not invoked if an exception was thrown from either of these
+ interception points.
+
+ * tao/IIOP_Transport.cpp (get_listen_point):
+
+ Use CORBA::String_var to improve exception safety, and simplify
+ the code.
+
+ Improved performance of this method by comparing the numerical
+ forms of the IP addresses for equality rather than the
+ stringified IP addresses or hostnames. This saves the cost of a
+ strcmp().
+
+ Another performance improvement: don't bother creating a
+ temporary IIOP::ListenPoint and then copying it to the
+ IIOP::ListenPointList. Just use the one that was already
+ created in the IIOP::ListenPointList.
+
+ Fixed busted code that casted away the const-ness of the
+ pointer to the INET_Addr array in the IIOP_Acceptor so that it
+ could be used as a temporary (modifiable!) variable. Since a
+ temporary INET_Addr was needed, just create one rather than
+ butchering what is supposed to be an immutable set of
+ INET_Addrs.
+
+ (send):
+
+ Use the peer's send_n() method instead of ACE::send_n(). This
+ is makes it clearer to pluggable protocol implementors that
+ ACE::send_n() should not always be used to when implementing
+ this method. For example, SSLIOP doesn't use ACE::send_n()
+ since the data being sent must be encrypted.
+
+ * tao/Invocation.h:
+ * tao/Invocation.cpp (generate_request_id):
+
+ New method for generating request IDs. It generates a request
+ ID based on the address of the TAO_GIOP_Invocation object. The
+ address is guaranteed to be unique within the process. This
+ makes it possible to generate a request ID without acquiring a
+ lock, which in turn allows to remove a lock from the critical
+ path. Neat, huh? :-) Things are slightly more complicated on
+ platforms with 64-bit addresses. On those platforms, we do some
+ bit manipulation and extract a 32-bit value from that address.
+ If all else fails, we fall back on the traditional request ID
+ generator that increments a CORBA::ULong atomically (i.e. by
+ acquiring a lock). [Bug 826]
+
+ (start):
+
+ Obtain a request ID from the new generate_request_id() method.
+
+ * tao/operation_details.h:
+
+ Cosmetic update.
+
+ * tao/operation_details.i (modify_request_id):
+
+ Do not adjust even-ness or odd-ness of the request ID by first
+ multiplying by two. It is not safe to do that since the request
+ ID may have been based on the address of the TAO_GIOP_Invocation
+ object (due to the above changes). In fact, it wasn't really
+ safe to multiply by two before the request ID optimization since
+ doing so may actually cause another outstanding request ID to be
+ re-used. Simply incrementing by one when appropriate is safer.
+
+ * tao/Asynch_Invocation.h:
+ * tao/Asynch_Invocation.cpp (generate_request_id):
+
+ Generate a request ID based on the address of the
+ TAO_Asynch_Reply_Dispatcher object. This is basically the same
+ optimization used in TAO_GIOP_Invocation. However, in the case
+ of AMI we need to used the TAO_Asynch_Reply_Dispatcher object
+ since it exists for the duration of the request, whereas the
+ Invocation object doesn't.
+
+ * tao/Sequence.i (length):
+
+ Optimized unbounded sequence growth. The internal buffer (hence
+ the maximum) now generally grows to twice the amount of the
+ previous maximum unless the desired length is larger than that
+ (doubled) value. The number of allocations and copies for large
+ numbers of small sequence length increases has been reduced
+ significantly by this optimization. For example, 8 sequence
+ length increases of 1 previously caused 8 allocations to occur
+ and 28 copies. The new scheme reduces those numbers to 4
+ allocations and 7 copies. This change should make insertion
+ constant on the average (similar to an STL vector). [Bug 757]
+
+ * tao/PortableServer/ServerRequestInfo.cpp (request_id):
+
+ Generate a request ID based on the address of the
+ TAO_ServerRequest object. The request ID generated by this
+ method need not be the same as the GIOP request ID sent with the
+ request. It just needs to be unique within a given process.
+ This is the same trick used in the TAO_GIOP_Invocation object
+ described above. [Bug 826]
+
+ * tests/BiDirectional_NestedUpcall/BiDirectional_NestedUpcall.dsw:
+ * tests/BiDirectional_NestedUpcall/client.dsp:
+ * tests/BiDirectional_NestedUpcall/server.dsp:
+
+ Added these missing MSVC C++ project files.
+
Tue Apr 10 12:13:48 2001 Jeff Parsons <parsons@cs.wustl.edu>
* tao/TypeCodeFactory/TAO_TypeCodeFactory_i.cpp:
diff --git a/TAO/tao/Asynch_Invocation.cpp b/TAO/tao/Asynch_Invocation.cpp
index eec74ba8c59..6b8644e4609 100644
--- a/TAO/tao/Asynch_Invocation.cpp
+++ b/TAO/tao/Asynch_Invocation.cpp
@@ -78,6 +78,41 @@ TAO_GIOP_Asynch_Invocation::start (CORBA::Environment &ACE_TRY_ENV)
#if (TAO_HAS_AMI_CALLBACK == 1) || (TAO_HAS_AMI_POLLER == 1)
+CORBA::ULong
+TAO_GIOP_Twoway_Asynch_Invocation::generate_request_id (void) const
+{
+ // The request ID must be unique across all outstanding requests.
+ // To avoid synchronization overhead, the address of the
+ // TAO_Asynch_Reply_Dispatcher object is used as the request ID.
+ // This guarantees that the request ID is unique.
+ //
+ // For 64-bit platforms, only the lower 32 bits are used. Hopefully
+ // that will be enough to ensure uniqueness.
+
+ // This is basically the same trick used in
+ // TAO_GIOP_Invocation::generate_request_id(). However, no right
+ // shifting of 64 bit addresses is performed since the
+ // TAO_Asynch_Reply_Dispatcher object is not large enough to allow
+ // that trick.
+
+ CORBA::ULong id = 0;
+
+ // 32 bit address
+ if (sizeof (this) == 4)
+ id =
+ ACE_reinterpret_cast (CORBA::ULong, this->rd_);
+
+ // 64 bit address -- use lower 32 bits
+ else if (sizeof (this) == 8)
+ id =
+ ACE_reinterpret_cast (CORBA::ULong, this->rd_) & 0xFFFFFFFFu;
+
+ else
+ id = this->transport_->tms ()->request_id (); // Fallback
+
+ return id;
+}
+
int
TAO_GIOP_Twoway_Asynch_Invocation::invoke_i (CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException))
diff --git a/TAO/tao/Asynch_Invocation.h b/TAO/tao/Asynch_Invocation.h
index 1ac4ebbd925..2390243cade 100644
--- a/TAO/tao/Asynch_Invocation.h
+++ b/TAO/tao/Asynch_Invocation.h
@@ -8,8 +8,7 @@
*
* Encapsulate the logic for remote Asynchronous Invocations.
*
- *
- * @author Carlos O'Ryan <coryan@cs.wustl.edu>
+ * @author Carlos O'Ryan <coryan@uci.edu>
* @author Alexander Babu Arulanthu <alex@cs.wustl.edu>
* @author Jeff Parsons <parsons@cs.wustl.edu>
*/
@@ -32,17 +31,17 @@
#include "tao/MessagingC.h"
#endif /* (TAO_HAS_AMI_CALLBACK == 1) || (TAO_HAS_AMI_POLLER == 1) == 0 */
+/**
+ * @class TAO_GIOP_Asynch_Invocation
+ *
+ * @brief Base class for TAO_GIOP_Twoway_Asynch_Invocation and
+ * TAO_GIOP_DII_Deferred_Invocation.
+ */
class TAO_Export TAO_GIOP_Asynch_Invocation
: public TAO_GIOP_Invocation
{
- // = TITLE
- // TAO_Asynch_Invocation.
- //
- // = DESCRIPTION
- // Base class for TAO_GIOP_Twoway_Asynch_Invocation and
- // TAO_GIOP_DII_Deferred_Invocation.
- //
public:
+
/// Default constructor. This should never get called, it is here
/// only to appease older versions of g++.
TAO_GIOP_Asynch_Invocation (void);
@@ -67,6 +66,7 @@ public:
ACE_THROW_SPEC ((CORBA::SystemException));
protected:
+
/// Must be overridden.
virtual int invoke_i (CORBA::Environment &ACE_TRY_ENV)
ACE_THROW_SPEC ((CORBA::SystemException)) = 0;
@@ -77,19 +77,20 @@ protected:
#if (TAO_HAS_AMI_CALLBACK == 1) || (TAO_HAS_AMI_POLLER == 1)
+/**
+ * @class TAO_GIOP_Twoway_Asynch_Invocation
+ *
+ * @brief Sends a two-way request does not expect the reply. This
+ * class connects (or lookups a connection from the cache) to
+ * the remote server, builds the CDR stream for the Request,
+ * send the CDR stream and returns.
+ */
class TAO_Export TAO_GIOP_Twoway_Asynch_Invocation
: public TAO_GIOP_Asynch_Invocation
{
- // = TITLE
- // TAO_GIOP_Twoway_Asynch_Invocation.
- //
- // = DESCRIPTION
- // Sends a two-way request does not expect the reply.
- // This class connects (or lookups a connection from the cache) to
- // the remote server, builds the CDR stream for the Request, send
- // the CDR stream and returns.
- //
+
public:
+
/// Constructor.
TAO_GIOP_Twoway_Asynch_Invocation (
TAO_Stub *stub,
@@ -102,6 +103,25 @@ public:
);
protected:
+
+ /// Generate a request ID for an asynchronous invocation
+ /**
+ * The request ID must be unique across all outstanding requests.
+ * To avoid synchronization overhead, the address of the
+ * TAO_Asynch_Reply_Dispatcher object is used as the request ID.
+ * This guarantees that the request ID is unique.
+ * @par
+ * For 64-bit platforms, only the lower 32 bits are used. Hopefully
+ * that will be enough to ensure uniqueness.
+ * @par
+ * This is basically the same trick used in
+ * TAO_GIOP_Invocation::generate_request_id(). However, no right
+ * shifting of 64 bit addresses is performed since the
+ * TAO_Asynch_Reply_Dispatcher object is not large enough to allow
+ * that trick.
+ */
+ virtual CORBA::ULong generate_request_id (void) const;
+
/// Implementation of the invoke() methods, handles the basic
/// send/reply code and the system exceptions.
virtual int invoke_i (CORBA::Environment &ACE_TRY_ENV)
diff --git a/TAO/tao/ClientRequestInfo.cpp b/TAO/tao/ClientRequestInfo.cpp
index bc93568befa..0ff821447e2 100644
--- a/TAO/tao/ClientRequestInfo.cpp
+++ b/TAO/tao/ClientRequestInfo.cpp
@@ -269,7 +269,7 @@ TAO_ClientRequestInfo::add_request_service_context (
TAO_Service_Context &service_context_list =
this->invocation_->request_service_context ();
- if (service_context_list.set_context (service_context,replace) == 0)
+ if (service_context_list.set_context (service_context, replace) == 0)
{
ACE_THROW (CORBA::BAD_INV_ORDER (TAO_OMG_VMCID | 11,
CORBA::COMPLETED_NO));
diff --git a/TAO/tao/ClientRequestInfo.h b/TAO/tao/ClientRequestInfo.h
index 3b559484d92..ef92b0c92c7 100644
--- a/TAO/tao/ClientRequestInfo.h
+++ b/TAO/tao/ClientRequestInfo.h
@@ -167,6 +167,7 @@ public:
* an extension used internally by TAO.
*/
//@{
+
/// Change the exception status.
void exception (CORBA::Exception *exception);
@@ -184,6 +185,7 @@ public:
//@}
protected:
+
/// Helper method to get the request and response service contexts.
IOP::ServiceContext *get_service_context_i (
TAO_Service_Context &service_context_list,
diff --git a/TAO/tao/IIOP_Transport.cpp b/TAO/tao/IIOP_Transport.cpp
index 4ff0432bbd4..522f3560f50 100644
--- a/TAO/tao/IIOP_Transport.cpp
+++ b/TAO/tao/IIOP_Transport.cpp
@@ -1,4 +1,5 @@
// This may look like C, but it's really -*- C++ -*-
+//
// $Id$
#include "tao/IIOP_Transport.h"
@@ -22,7 +23,9 @@
# include "tao/IIOP_Transport.i"
#endif /* ! __ACE_INLINE__ */
-ACE_RCSID (tao, IIOP_Transport, "$Id$")
+ACE_RCSID (TAO,
+ IIOP_Transport,
+ "$Id$")
TAO_IIOP_Transport::TAO_IIOP_Transport (TAO_IIOP_Connection_Handler *handler,
TAO_ORB_Core *orb_core,
@@ -38,7 +41,7 @@ TAO_IIOP_Transport::TAO_IIOP_Transport (TAO_IIOP_Connection_Handler *handler,
ACE_NEW (this->messaging_object_,
TAO_GIOP_Message_Lite (orb_core));
}
- else
+ else
{
// Use the normal GIOP object
ACE_NEW (this->messaging_object_,
@@ -107,7 +110,8 @@ TAO_IIOP_Transport::read_process_message (ACE_Time_Value *max_wait_time,
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("TAO (%P|%t) - %p\n"),
- ACE_TEXT ("IIOP_Transport::read_message, failure in read_message ()")));
+ ACE_TEXT ("IIOP_Transport::read_message, failure ")
+ ACE_TEXT ("in read_message ()")));
this->tms_->connection_closed ();
return -1;
@@ -210,7 +214,6 @@ TAO_IIOP_Transport::send_message (TAO_OutputCDR &stream,
return 1;
}
-
int
TAO_IIOP_Transport::generate_request_header (TAO_Operation_Details &opdetails,
TAO_Target_Specification &spec,
@@ -226,7 +229,7 @@ TAO_IIOP_Transport::generate_request_header (TAO_Operation_Details &opdetails,
{
this->set_bidir_context_info (opdetails);
- // Set the flag to 0
+ // Set the flag to 0 (i.e., originating side)
this->bidirectional_flag (0);
}
@@ -256,14 +259,14 @@ TAO_IIOP_Transport::tear_listen_point_list (TAO_InputCDR &cdr)
if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
return -1;
- cdr.reset_byte_order (ACE_static_cast(int,byte_order));
+ cdr.reset_byte_order (ACE_static_cast (int, byte_order));
IIOP::ListenPointList listen_list;
if ((cdr >> listen_list) == 0)
return -1;
// As we have received a bidirectional information, set the flag to
- // 1
+ // 1 (i.e., non-originating side)
this->bidirectional_flag (1);
return this->connection_handler_->process_listen_point_list (listen_list);
}
@@ -289,29 +292,30 @@ TAO_IIOP_Transport::process_message (void)
}
else if (t == TAO_PLUGGABLE_MESSAGE_REQUEST)
{
- if (this->messaging_object_->process_request_message (this,
- this->orb_core ()) == -1)
+ if (this->messaging_object_->process_request_message (
+ this,
+ this->orb_core ()) == -1)
return -1;
}
else if (t == TAO_PLUGGABLE_MESSAGE_REPLY)
{
TAO_Pluggable_Reply_Params params (this->orb_core ());
+
if (this->messaging_object_->process_reply_message (params) == -1)
{
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("TAO (%P|%t) - %p\n"),
- ACE_TEXT ("IIOP_Transport::process_message, process_reply_message ()")));
+ ACE_TEXT ("IIOP_Transport::process_message, ")
+ ACE_TEXT ("process_reply_message ()")));
this->messaging_object_->reset ();
this->tms_->connection_closed ();
return -1;
}
-
- result =
- this->tms_->dispatch_reply (params);
+ result = this->tms_->dispatch_reply (params);
// @@ Somehow it seems dangerous to reset the state *after*
// dispatching the request, what if another threads receives
@@ -342,8 +346,6 @@ TAO_IIOP_Transport::process_message (void)
// is going to take a look please contact bala@cs.wustl.edu
// for details on this-- Bala
-
-
if (result == -1)
{
// Something really critical happened, we will forget about
@@ -391,8 +393,7 @@ TAO_IIOP_Transport::process_message (void)
void
TAO_IIOP_Transport::set_bidir_context_info (TAO_Operation_Details &opdetails)
{
-
- // Get a handle on to the acceptor registry
+ // Get a handle to the acceptor registry
TAO_Acceptor_Registry * ar =
this->orb_core ()->acceptor_registry ();
@@ -409,6 +410,8 @@ TAO_IIOP_Transport::set_bidir_context_info (TAO_Operation_Details &opdetails)
// Check whether it is a IIOP acceptor
if ((*acceptor)->tag () == TAO_TAG_IIOP_PROFILE)
{
+ // @@ Why isn't the return value checked!
+ // -Ossama
this->get_listen_point (listen_point_list,
*acceptor);
}
@@ -419,7 +422,7 @@ TAO_IIOP_Transport::set_bidir_context_info (TAO_Operation_Details &opdetails)
TAO_OutputCDR cdr;
// Marshall the information into the stream
- if ((cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)== 0)
+ if ((cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER) == 0)
|| (cdr << listen_point_list) == 0)
return;
@@ -430,7 +433,6 @@ TAO_IIOP_Transport::set_bidir_context_info (TAO_Operation_Details &opdetails)
return;
}
-
int
TAO_IIOP_Transport::get_listen_point (
IIOP::ListenPointList &listen_point_list,
@@ -440,11 +442,11 @@ TAO_IIOP_Transport::get_listen_point (
ACE_dynamic_cast (TAO_IIOP_Acceptor *,
acceptor );
- // Get the array of endpoints serviced by <iiop_acceptor>
+ // Get the array of endpoints serviced by TAO_IIOP_Acceptor
const ACE_INET_Addr *endpoint_addr =
iiop_acceptor->endpoints ();
- // Get the count
+ // Get the endpoint count
size_t count =
iiop_acceptor->endpoint_count ();
@@ -455,21 +457,21 @@ TAO_IIOP_Transport::get_listen_point (
== -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
- ACE_TEXT ("(%P|%t) Could not resolve local host")
- ACE_TEXT (" address in set_bidir_context_info () \n")),
+ ACE_TEXT ("(%P|%t) Could not resolve local ")
+ ACE_TEXT ("host address in ")
+ ACE_TEXT ("get_listen_point()\n")),
-1);
}
-
// Note: Looks like there is no point in sending the list of
// endpoints on interfaces on which this connection has not
// been established. If this is wrong, please correct me.
- char *local_interface = 0;
+ CORBA::String_var local_interface;
// Get the hostname for the local address
if (iiop_acceptor->hostname (this->orb_core_,
local_addr,
- local_interface) == -1)
+ local_interface.out ()) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%P|%t) Could not resolve local host")
@@ -477,61 +479,50 @@ TAO_IIOP_Transport::get_listen_point (
-1);
}
- ACE_INET_Addr *tmp_addr = ACE_const_cast (ACE_INET_Addr *,
- endpoint_addr);
-
for (size_t index = 0;
index <= count;
index++)
{
+ ACE_INET_Addr tmp_addr;
+ CORBA::String_var acceptor_interface;
+
// Get the listen point on that acceptor if it has the same
// interface on which this connection is established
- char *acceptor_interface = 0;
-
if (iiop_acceptor->hostname (this->orb_core_,
- tmp_addr[index],
- acceptor_interface) == -1)
+ tmp_addr,
+ acceptor_interface.out ()) == -1)
continue;
- // @@ This is very bad for performance, but it is a one time
- // affair
- if (ACE_OS::strcmp (local_interface,
- acceptor_interface) == 0)
+ if (local_addr.get_ip_address()
+ == endpoint_addr[index].get_ip_address())
{
- // We have the connection and the acceptor endpoint on the
- // same interface
- IIOP::ListenPoint point;
- point.host = CORBA::string_dup (local_interface);
- point.port = endpoint_addr[index].get_port_number ();
-
// Get the count of the number of elements
CORBA::ULong len = listen_point_list.length ();
// Increase the length by 1
listen_point_list.length (len + 1);
- // Add the new length to the list
- listen_point_list[len] = point;
+ // We have the connection and the acceptor endpoint on the
+ // same interface
+ IIOP::ListenPoint &point = listen_point_list[len];
+ point.host = CORBA::string_dup (local_interface.in ());
+ point.port = endpoint_addr[index].get_port_number ();
}
-
- // @@ This is bad....
- CORBA::string_free (acceptor_interface);
}
- CORBA::string_free (local_interface);
return 1;
}
void
TAO_IIOP_Transport::transition_handler_state_i (void)
{
- connection_handler_ = 0;
+ this->connection_handler_ = 0;
}
#if 0
TAO_Connection_Handler*
TAO_IIOP_Transport::connection_handler (void) const
{
- return connection_handler_;
+ return this->connection_handler_;
}
#endif
diff --git a/TAO/tao/Invocation.cpp b/TAO/tao/Invocation.cpp
index 507e73b406e..a19ca539576 100644
--- a/TAO/tao/Invocation.cpp
+++ b/TAO/tao/Invocation.cpp
@@ -31,7 +31,9 @@
# include "Invocation.i"
#endif /* ! __ACE_INLINE__ */
-ACE_RCSID(tao, Invocation, "$Id$")
+ACE_RCSID (TAO,
+ Invocation,
+ "$Id$")
#if defined (ACE_ENABLE_TIMEPROBES)
@@ -304,9 +306,8 @@ TAO_GIOP_Invocation::start (CORBA::Environment &ACE_TRY_ENV)
countdown.update ();
}
- // Obtain unique request id from the RMS.
- this->op_details_.request_id (
- this->transport_->tms ()->request_id ());
+ // Set the unique request ID associated with this request.
+ this->op_details_.request_id (this->generate_request_id ());
// Make sure that you have the right object key
this->target_spec_.target_specifier (this->profile_->object_key ());
@@ -387,6 +388,64 @@ TAO_GIOP_Invocation::prepare_header (CORBA::Octet response_flags,
}
}
+CORBA::ULong
+TAO_GIOP_Invocation::generate_request_id (void) const
+{
+ // The request ID must be unique across all outstanding requests.
+ // To avoid synchronization overhead, the address of this Invocation
+ // object is used as the request ID. This guarantees that the
+ // request ID is unique without being forced to acquire a lock.
+ //
+ // For 64-bit platforms, we right shift 8 bits and then use the
+ // lower 32 bits of that shifted value. Rather than losing the
+ // upper 32 bits of significant digits by taking the lower 32 bits,
+ // we only lose the upper 24 by doing the shift. Basically, the
+ // resulting request ID will comprised of bits 8 through 39. This is
+ // made possible by the fact that this Invocation object is large
+ // enough to increase the likelihood that those bits (0 through 39)
+ // are unique. In particular, this->buffer_ is 512 bytes
+ // (ACE_CDR::DEFAULT_BUFSIZE) long by default; implying that
+ // dropping the lower 8 bits of the this Invocation object's 64 bit
+ // address (i.e. 256 bytes) is not a problem.
+
+ CORBA::ULong id = 0;
+
+ // 32 bit address
+ if (sizeof (this) == 4)
+ id = ACE_reinterpret_cast (CORBA::ULong, this);
+
+ // 64 bit address -- bits 8 through 39 (see notes above!)
+ // In this case, we make sure this object is large enough to safely
+ // do the right shift. This is necessary since the size of the
+ // buffer that makes this object is configurable.
+ else if (sizeof (this) == 8
+ && sizeof (*this) > 256 /* 2 << 8 */)
+ id =
+ (ACE_reinterpret_cast (CORBA::ULong, this) >> 8) & 0xFFFFFFFFu;
+
+ // 64 bit address -- lower 32 bits
+ //
+ else if (sizeof (this) == 8)
+ id = ACE_reinterpret_cast (CORBA::ULong, this) & 0xFFFFFFFFu;
+
+ // @@ The following request ID generator prevents the
+ // PortableInterceptor::ClientRequestInterceptor::send_request()
+ // interception point from occuring before the call to connect,
+ // thus preventing us from adding an optimization that itself
+ // prevents a connection from being unnecessarily performed.
+ // Thus, the ClientRequestInfo object is forced to have its own
+ // request ID generator in order to make it possible to implement
+ // the above optimization.
+ //
+ // Ideally, this request ID generator should go away, especially
+ // since it adds a lock to the critical path.
+ else // Fallback
+ id = this->transport_->tms ()->request_id ();
+
+ return id;
+}
+
+
// Send request.
int
TAO_GIOP_Invocation::invoke (CORBA::Boolean is_roundtrip,
diff --git a/TAO/tao/Invocation.h b/TAO/tao/Invocation.h
index c6f26b9727e..10240976278 100644
--- a/TAO/tao/Invocation.h
+++ b/TAO/tao/Invocation.h
@@ -10,14 +10,12 @@
* twoways.
*
* THREADING NOTE: Threads should never manipulate another
- * thread's invocations. In this implementation, all data
- * structures used to represent invocations (and parts of them)
- * are owned by the thread which created them. Multiple threads
- * may make of course concurrent invocations safely, since the
- * GIOP code is reentrant.
+ * thread's invocations. In this implementation, all data structures
+ * used to represent invocations (and parts of them) are owned by the
+ * thread which created them. Multiple threads may make of course
+ * concurrent invocations safely, since the GIOP code is reentrant.
*
- *
- * @author Carlos O'Ryan <coryan@cs.wustl.edu>
+ * @author Carlos O'Ryan <coryan@uci.edu>
* @author Alexander Babu Arulanthu <alex@cs.wustl.edu>
*/
//=============================================================================
@@ -122,8 +120,29 @@ public:
/// after receiving a reply message.
TAO_Service_Context& reply_service_context (void);
+ /// Generate a request ID
+ /**
+ * The request ID must be unique across all outstanding requests.
+ * To avoid synchronization overhead, the address of this Invocation
+ * object is used as the request ID. This guarantees that the
+ * request ID is unique without being forced to acquire a lock.
+ * @par
+ * For 64-bit platforms, we right shift 8 bits and then use the
+ * lower 32 bits of that shifted value. Rather than losing the
+ * upper 32 bits of significant digits by taking the lower 32 bits,
+ * we only lose the upper 24 by doing the shift. Basically, the
+ * resulting request ID will comprised of bits 8 through 39. This is
+ * made possible by the fact that this Invocation object is large
+ * enough to increase the likelihood that those bits (0 through 39)
+ * are unique. In particular, this->buffer_ is 512 bytes
+ * (ACE_CDR::DEFAULT_BUFSIZE) long by default; implying that
+ * dropping the lower 8 bits of the this Invocation object's 64 bit
+ * address (i.e. 256 bytes) is not a problem.
+ */
+ virtual CORBA::ULong generate_request_id (void) const;
+
/// Return the request id of this invocation.
- CORBA::ULong request_id (void);
+ CORBA::ULong request_id (void) const;
/// Return the name of the operation being invoked.
const char *operation (void);
diff --git a/TAO/tao/Invocation.i b/TAO/tao/Invocation.i
index 98e1766fcfc..109904cfb81 100644
--- a/TAO/tao/Invocation.i
+++ b/TAO/tao/Invocation.i
@@ -15,7 +15,7 @@ TAO_GIOP_Invocation::reply_service_context (void)
}
ACE_INLINE CORBA::ULong
-TAO_GIOP_Invocation::request_id (void)
+TAO_GIOP_Invocation::request_id (void) const
{
return this->op_details_.request_id ();
}
diff --git a/TAO/tao/PortableInterceptor.cpp b/TAO/tao/PortableInterceptor.cpp
index 6bc4021d9a3..6d30c7f083a 100644
--- a/TAO/tao/PortableInterceptor.cpp
+++ b/TAO/tao/PortableInterceptor.cpp
@@ -1,18 +1,157 @@
// $Id$:
-#include "tao/PortableInterceptor.h"
+#include "PortableInterceptor.h"
#if TAO_HAS_INTERCEPTORS == 1
#if !defined (__ACE_INLINE__)
-#include "tao/PortableInterceptor.i"
+#include "PortableInterceptor.i"
#endif /* defined INLINE */
+#include "ClientRequestInfo.h"
+
TAO_ClientRequestInterceptor_Adapter::
~TAO_ClientRequestInterceptor_Adapter (void)
{
}
+void
+TAO_ClientRequestInterceptor_Adapter::
+send_request (TAO_ClientRequestInfo *ri,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ // This method implements one of the "starting" client side
+ // interception point.
+ for (size_t i = 0 ; i < this->len_; ++i)
+ {
+ this->interceptors_[i]->send_request (ri
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // The starting interception point completed successfully. Push
+ // the interceptor on to the flow stack.
+ ++this->stack_size_;
+ }
+
+ ACE_UNUSED_ARG (ACE_TRY_ENV);
+}
+
+ACE_INLINE void
+TAO_ClientRequestInterceptor_Adapter::
+receive_reply (TAO_ClientRequestInfo *ri,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ // This is an "ending" interception point so we only process the
+ // interceptors pushed on to the flow stack.
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending"
+ // interception point.
+
+ // Unwind the stack.
+ size_t len = this->stack_size_;
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor already
+ // invoked in this "ending" interception point from being
+ // invoked in another "ending" interception point.
+ --this->stack_size_;
+
+ this->interceptors_[this->stack_size_]->receive_reply (
+ ri
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ ACE_UNUSED_ARG (ACE_TRY_ENV);
+
+}
+
+ACE_INLINE void
+TAO_ClientRequestInterceptor_Adapter::
+receive_exception (TAO_ClientRequestInfo *ri,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ // This is an "ending" interception point so we only process the
+ // interceptors pushed on to the flow stack.
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending"
+ // interception point.
+
+ ACE_TRY
+ {
+ // Unwind the flow stack.
+ size_t len = this->stack_size_;
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor
+ // already invoked in this "ending" interception point from
+ // being invoked in another "ending" interception point.
+ --this->stack_size_;
+
+ this->interceptors_[this->stack_size_]->receive_exception (
+ ri
+ TAO_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCHANY
+ {
+ // The receive_exception() interception point in the remaining
+ // interceptors must be called so call this method (not the
+ // interceptor's corresponding method) recursively. The call is
+ // made recursively since the caught exception must survive
+ // until the remaining interceptors have been called.
+
+ // Note that the recursion will stop once the flow stack size
+ // drops to zero, i.e., once each interceptor has been invoked.
+ // This prevents infinite recursion from occuring.
+
+ ri->exception (&ACE_ANY_EXCEPTION);
+
+ this->receive_exception (ri, ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ ACE_RE_THROW;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+}
+
+ACE_INLINE void
+TAO_ClientRequestInterceptor_Adapter::
+receive_other (TAO_ClientRequestInfo *ri,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ // This is an "ending" interception point so we only process the
+ // interceptors pushed on to the flow stack.
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending"
+ // interception point.
+
+ // Unwind the stack.
+ size_t len = this->stack_size_;
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor already
+ // invoked in this "ending" interception point from being
+ // invoked in another "ending" interception point.
+ --this->stack_size_;
+
+ this->interceptors_[this->stack_size_]->receive_other (
+ ri
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ ACE_UNUSED_ARG (ACE_TRY_ENV);
+
+}
+
// -------------------------------------------------------------------
TAO_ServerRequestInterceptor_Adapter::
@@ -20,4 +159,176 @@ TAO_ServerRequestInterceptor_Adapter::
{
}
+ACE_INLINE void
+TAO_ServerRequestInterceptor_Adapter::
+receive_request_service_contexts (
+ PortableInterceptor::ServerRequestInfo_ptr ri,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ // This method implements one of the "starting" server side
+ // interception point.
+ for (size_t i = 0 ; i < this->len_; ++i)
+ {
+ this->interceptors_[i]->receive_request_service_contexts (
+ ri
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // The starting interception point completed successfully. Push
+ // the interceptor on to the flow stack.
+ ++this->stack_size_;
+ }
+
+ ACE_UNUSED_ARG (ACE_TRY_ENV);
+}
+
+ACE_INLINE void
+TAO_ServerRequestInterceptor_Adapter::
+receive_request (PortableInterceptor::ServerRequestInfo_ptr ri,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ // This method implements an "intermediate" server side interception
+ // point. Interceptors are invoked in the same order they were
+ // pushed on to the flow stack.
+
+ if (this->len_ != this->stack_size_)
+ {
+ // This method (i.e. the receive_request() interception point)
+ // should only be invoked if all of the interceptors registered
+ // with the ORB were pushed on to the flow stack by one of the
+ // starting endpoints (such as
+ // receive_request_service_contexts()). If the above condition
+ // evaluates to "true," then it is likely that a starting
+ // interception point was never invoked. This is of course, an
+ // internal error that must be corrected.
+ ACE_THROW (CORBA::INTERNAL ());
+ }
+
+ for (size_t i = 0; i < this->stack_size_; ++i)
+ {
+ this->interceptors_[i]->receive_request (ri
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Note that no interceptors are pushed on to or popped off of
+ // the flow stack in this interception point since it is an
+ // intermediate interception point.
+ }
+}
+
+ACE_INLINE void
+TAO_ServerRequestInterceptor_Adapter::
+send_reply (PortableInterceptor::ServerRequestInfo_ptr ri,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ // This is an "ending" interception point so we only process the
+ // interceptors pushed on to the flow stack.
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending"
+ // interception point.
+
+ // Unwind the stack.
+ size_t len = this->stack_size_;
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor already
+ // invoked in this "ending" interception point from being
+ // invoked in another "ending" interception point.
+ --this->stack_size_;
+
+ this->interceptors_[this->stack_size_]->send_reply (
+ ri
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ ACE_UNUSED_ARG (ACE_TRY_ENV);
+}
+
+ACE_INLINE void
+TAO_ServerRequestInterceptor_Adapter::
+send_exception (PortableInterceptor::ServerRequestInfo_ptr ri,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ // This is an "ending" server side interception point so we only
+ // process the interceptors pushed on to the flow stack.
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending" server
+ // side interception point.
+
+ ACE_TRY
+ {
+ // Unwind the flow stack.
+ size_t len = this->stack_size_;
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor
+ // already invoked in this "ending" interception point from
+ // being invoked in another "ending" interception point.
+ --this->stack_size_;
+
+ this->interceptors_[this->stack_size_]->send_exception (
+ ri
+ TAO_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCHANY
+ {
+ // The send_exception() interception point in the remaining
+ // interceptors must be called so call this method (not the
+ // interceptor's corresponding method) recursively. The call is
+ // made recursively since the caught exception must survive
+ // until the remaining interceptors have been called.
+ //
+ // Note that the recursion will stop once the flow stack size
+ // drops to zero, i.e., once each interceptor has been invoked.
+ // This prevents infinite recursion from occuring.
+
+ // @@ FIXME! UNCOMMENT!
+ // ri->exception (&ACE_ANY_EXCEPTION);
+
+ this->send_exception (ri, ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ ACE_RE_THROW;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+}
+
+ACE_INLINE void
+TAO_ServerRequestInterceptor_Adapter::
+send_other (PortableInterceptor::ServerRequestInfo_ptr ri,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ // This is an "ending" server side interception point so we only
+ // process the interceptors pushed on to the flow stack.
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending" server
+ // side interception point.
+
+ // Unwind the flow stack.
+ size_t len = this->stack_size_;
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor already
+ // invoked in this "ending" interception point from being
+ // invoked in another "ending" interception point.
+ --this->stack_size_;
+
+ this->interceptors_[this->stack_size_]->send_other (
+ ri
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ ACE_UNUSED_ARG (ACE_TRY_ENV);
+}
+
#endif /* TAO_HAS_INTERCEPTORS == 1 */
diff --git a/TAO/tao/PortableInterceptor.h b/TAO/tao/PortableInterceptor.h
index 7de8a35d92c..730a87119af 100644
--- a/TAO/tao/PortableInterceptor.h
+++ b/TAO/tao/PortableInterceptor.h
@@ -14,8 +14,6 @@
* These macros allows us to disable/enable support of interceptors
* easily.
*
- *
- *
* @author Nanbor Wang <nanbor@cs.wustl.edu>
* @author Kirthika Parameswaran <kirthika@cs.wustl.edu>
* @author Ossama Othman <ossama@uci.edu>
@@ -53,6 +51,9 @@
#include "PortableInterceptorC.h"
#include "Interceptor_List.h"
+// Forward declarations
+class TAO_ClientRequestInfo;
+
/**
* @class TAO_ClientRequestInterceptor_Adapter
*
@@ -85,22 +86,22 @@ public:
//@{
/// This method implements one of the "starting" client side
/// interception points.
- void send_request (PortableInterceptor::ClientRequestInfo_ptr ri,
+ void send_request (TAO_ClientRequestInfo *ri,
CORBA::Environment &);
/// This method implements one of the "ending" client side
/// interception point.
- void receive_reply (PortableInterceptor::ClientRequestInfo_ptr ri,
+ void receive_reply (TAO_ClientRequestInfo *ri,
CORBA::Environment &);
/// This method implements one of the "ending" client side
/// interception point.
- void receive_exception (PortableInterceptor::ClientRequestInfo_ptr ri,
+ void receive_exception (TAO_ClientRequestInfo *ri,
CORBA::Environment &);
/// This method implements one of the "ending" client side
/// interception point.
- void receive_other (PortableInterceptor::ClientRequestInfo_ptr ri,
+ void receive_other (TAO_ClientRequestInfo *ri,
CORBA::Environment &);
//@}
diff --git a/TAO/tao/PortableInterceptor.i b/TAO/tao/PortableInterceptor.i
index 83b10444fef..8d607f70c47 100644
--- a/TAO/tao/PortableInterceptor.i
+++ b/TAO/tao/PortableInterceptor.i
@@ -12,122 +12,6 @@ TAO_ClientRequestInterceptor_Adapter::TAO_ClientRequestInterceptor_Adapter
this->len_ = interceptors.size ();
}
-ACE_INLINE void
-TAO_ClientRequestInterceptor_Adapter::
-send_request (PortableInterceptor::ClientRequestInfo_ptr ri,
- CORBA::Environment &ACE_TRY_ENV)
-{
- // This method implements one of the "starting" client side
- // interception point.
- for (size_t i = 0 ; i < this->len_; ++i)
- {
- this->interceptors_[i]->send_request (ri
- TAO_ENV_ARG_PARAMETER);
- ACE_CHECK;
-
- // The starting interception point completed successfully. Push
- // the interceptor on to the flow stack.
- ++this->stack_size_;
- }
-
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-}
-
-ACE_INLINE void
-TAO_ClientRequestInterceptor_Adapter::
-receive_reply (PortableInterceptor::ClientRequestInfo_ptr ri,
- CORBA::Environment &ACE_TRY_ENV)
-{
- // This is an "ending" interception point so we only process the
- // interceptors pushed on to the flow stack.
-
- // Notice that the interceptors are processed in the opposite order
- // they were pushed onto the stack since this is an "ending"
- // interception point.
-
- // Unwind the stack.
- size_t len = this->stack_size_;
- for (size_t i = 0; i < len; ++i)
- {
- // Pop the interceptor off of the flow stack before it is
- // invoked. This is necessary to prevent an interceptor already
- // invoked in this "ending" interception point from being
- // invoked in another "ending" interception point.
- --this->stack_size_;
-
- this->interceptors_[this->stack_size_]->receive_reply (
- ri
- TAO_ENV_ARG_PARAMETER);
- ACE_CHECK;
- }
-
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-
-}
-
-ACE_INLINE void
-TAO_ClientRequestInterceptor_Adapter::
-receive_exception (PortableInterceptor::ClientRequestInfo_ptr ri,
- CORBA::Environment &ACE_TRY_ENV)
-{
- // This is an "ending" interception point so we only process the
- // interceptors pushed on to the flow stack.
-
- // Notice that the interceptors are processed in the opposite order
- // they were pushed onto the stack since this is an "ending"
- // interception point.
-
- // Unwind the flow stack.
- size_t len = this->stack_size_;
- for (size_t i = 0; i < len; ++i)
- {
- // Pop the interceptor off of the flow stack before it is
- // invoked. This is necessary to prevent an interceptor already
- // invoked in this "ending" interception point from being
- // invoked in another "ending" interception point.
- --this->stack_size_;
-
- this->interceptors_[this->stack_size_]->receive_exception (
- ri
- TAO_ENV_ARG_PARAMETER);
- ACE_CHECK;
- }
-
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-}
-
-ACE_INLINE void
-TAO_ClientRequestInterceptor_Adapter::
-receive_other (PortableInterceptor::ClientRequestInfo_ptr ri,
- CORBA::Environment &ACE_TRY_ENV)
-{
- // This is an "ending" interception point so we only process the
- // interceptors pushed on to the flow stack.
-
- // Notice that the interceptors are processed in the opposite order
- // they were pushed onto the stack since this is an "ending"
- // interception point.
-
- // Unwind the stack.
- size_t len = this->stack_size_;
- for (size_t i = 0; i < len; ++i)
- {
- // Pop the interceptor off of the flow stack before it is
- // invoked. This is necessary to prevent an interceptor already
- // invoked in this "ending" interception point from being
- // invoked in another "ending" interception point.
- --this->stack_size_;
-
- this->interceptors_[this->stack_size_]->receive_other (
- ri
- TAO_ENV_ARG_PARAMETER);
- ACE_CHECK;
- }
-
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-
-}
-
// -------------------------------------------------------------------
ACE_INLINE
@@ -140,153 +24,3 @@ TAO_ServerRequestInterceptor_Adapter::TAO_ServerRequestInterceptor_Adapter
{
this->len_ = interceptors.size ();
}
-
-ACE_INLINE void
-TAO_ServerRequestInterceptor_Adapter::
-receive_request_service_contexts (
- PortableInterceptor::ServerRequestInfo_ptr ri,
- CORBA::Environment &ACE_TRY_ENV)
-{
- // This method implements one of the "starting" server side
- // interception point.
- for (size_t i = 0 ; i < this->len_; ++i)
- {
- this->interceptors_[i]->receive_request_service_contexts (
- ri
- TAO_ENV_ARG_PARAMETER);
- ACE_CHECK;
-
- // The starting interception point completed successfully. Push
- // the interceptor on to the flow stack.
- ++this->stack_size_;
- }
-
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-}
-
-ACE_INLINE void
-TAO_ServerRequestInterceptor_Adapter::
-receive_request (PortableInterceptor::ServerRequestInfo_ptr ri,
- CORBA::Environment &ACE_TRY_ENV)
-{
- // This method implements an "intermediate" server side interception
- // point. Interceptors are invoked in the same order they were
- // pushed on to the flow stack.
-
- if (this->len_ != this->stack_size_)
- {
- // This method (i.e. the receive_request() interception point)
- // should only be invoked if all of the interceptors registered
- // with the ORB were pushed on to the flow stack by one of the
- // starting endpoints (such as
- // receive_request_service_contexts()). If the above condition
- // evaluates to "true," then it is likely that a starting
- // interception point was never invoked. This is of course, an
- // internal error that must be corrected.
- ACE_THROW (CORBA::INTERNAL ());
- }
-
- for (size_t i = 0; i < this->stack_size_; ++i)
- {
- this->interceptors_[i]->receive_request (ri
- TAO_ENV_ARG_PARAMETER);
- ACE_CHECK;
-
- // Note that no interceptors are pushed on to or popped off of
- // the flow stack in this interception point since it is an
- // intermediate interception point.
- }
-}
-
-ACE_INLINE void
-TAO_ServerRequestInterceptor_Adapter::
-send_reply (PortableInterceptor::ServerRequestInfo_ptr ri,
- CORBA::Environment &ACE_TRY_ENV)
-{
- // This is an "ending" interception point so we only process the
- // interceptors pushed on to the flow stack.
-
- // Notice that the interceptors are processed in the opposite order
- // they were pushed onto the stack since this is an "ending"
- // interception point.
-
- // Unwind the stack.
- size_t len = this->stack_size_;
- for (size_t i = 0; i < len; ++i)
- {
- // Pop the interceptor off of the flow stack before it is
- // invoked. This is necessary to prevent an interceptor already
- // invoked in this "ending" interception point from being
- // invoked in another "ending" interception point.
- --this->stack_size_;
-
- this->interceptors_[this->stack_size_]->send_reply (
- ri
- TAO_ENV_ARG_PARAMETER);
- ACE_CHECK;
- }
-
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-}
-
-ACE_INLINE void
-TAO_ServerRequestInterceptor_Adapter::
-send_exception (PortableInterceptor::ServerRequestInfo_ptr ri,
- CORBA::Environment &ACE_TRY_ENV)
-{
- // This is an "ending" server side interception point so we only
- // process the interceptors pushed on to the flow stack.
-
- // Notice that the interceptors are processed in the opposite order
- // they were pushed onto the stack since this is an "ending" server
- // side interception point.
-
- // Unwind the flow stack.
- size_t len = this->stack_size_;
- for (size_t i = 0; i < len; ++i)
- {
- // Pop the interceptor off of the flow stack before it is
- // invoked. This is necessary to prevent an interceptor already
- // invoked in this "ending" interception point from being
- // invoked in another "ending" interception point.
- --this->stack_size_;
-
- this->interceptors_[this->stack_size_]->send_exception (
- ri
- TAO_ENV_ARG_PARAMETER);
- ACE_CHECK;
- }
-
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-}
-
-ACE_INLINE void
-TAO_ServerRequestInterceptor_Adapter::
-send_other (PortableInterceptor::ServerRequestInfo_ptr ri,
- CORBA::Environment &ACE_TRY_ENV)
-{
- // This is an "ending" server side interception point so we only
- // process the interceptors pushed on to the flow stack.
-
- // Notice that the interceptors are processed in the opposite order
- // they were pushed onto the stack since this is an "ending" server
- // side interception point.
-
- // Unwind the flow stack.
- size_t len = this->stack_size_;
- for (size_t i = 0; i < len; ++i)
- {
- // Pop the interceptor off of the flow stack before it is
- // invoked. This is necessary to prevent an interceptor already
- // invoked in this "ending" interception point from being
- // invoked in another "ending" interception point.
- --this->stack_size_;
-
- this->interceptors_[this->stack_size_]->send_other (
- ri
- TAO_ENV_ARG_PARAMETER);
- ACE_CHECK;
- }
-
- ACE_UNUSED_ARG (ACE_TRY_ENV);
-}
diff --git a/TAO/tao/PortableServer/ServerRequestInfo.cpp b/TAO/tao/PortableServer/ServerRequestInfo.cpp
index 05f48b2e885..0650252ce8c 100644
--- a/TAO/tao/PortableServer/ServerRequestInfo.cpp
+++ b/TAO/tao/PortableServer/ServerRequestInfo.cpp
@@ -22,7 +22,7 @@ TAO_ServerRequestInfo::TAO_ServerRequestInfo (
: server_request_ (server_request),
forward_reference_ (),
// poa_current_ (),
- adapter_id_ (),
+ // adapter_id_ (),
caught_exception_ (0),
reply_status_ (-1)
{
@@ -32,7 +32,38 @@ CORBA::ULong
TAO_ServerRequestInfo::request_id (CORBA::Environment &)
ACE_THROW_SPEC ((CORBA::SystemException))
{
- return this->server_request_.request_id ();
+ // The request ID returned by this method need not correspond to the
+ // GIOP request ID sent with the client request. The request ID
+ // must be unique across all outstanding requests. To avoid locking
+ // overhead, the address of the TAO_ServerRequest object is used as
+ // the request ID. This guarantees that the request ID is unique.
+ //
+ // For 64-bit platforms, only the lower 32 bits are used. Hopefully
+ // that will be enough to ensure uniqueness.
+
+ // This is basically the same trick used in
+ // TAO_GIOP_Invocation::generate_request_id(). However, no right
+ // shifting of 64 bit addresses is performed since the
+ // TAO_ServerRequest object is not large enough to allow that trick.
+
+ CORBA::ULong id = 0;
+
+ if (sizeof (this) == 4) // 32 bit address
+ id =
+ ACE_reinterpret_cast (CORBA::ULong, &(this->server_request_));
+
+ else if (sizeof (this) == 8) // 64 bit address -- use lower 32 bits
+ id =
+ ACE_reinterpret_cast (CORBA::ULong,
+ &(this->server_request_)) & 0xFFFFFFFFu;
+
+ else
+ // @@ Rather than fallback on the GIOP request ID, we should use
+ // an atomically incremented variable specific to the ORB, or
+ // perhaps specific to the process.
+ id = this->server_request_.request_id (); // Fallback
+
+ return id;
}
char *
@@ -384,7 +415,7 @@ TAO_ServerRequestInfo::add_reply_service_context (
TAO_Service_Context &service_context_list =
this->server_request_.reply_service_context ();
- if (service_context_list.set_context (service_context,replace) == 0)
+ if (service_context_list.set_context (service_context, replace) == 0)
{
ACE_THROW (CORBA::BAD_INV_ORDER (TAO_OMG_VMCID | 11,
CORBA::COMPLETED_NO));
diff --git a/TAO/tao/PortableServer/ServerRequestInfo.h b/TAO/tao/PortableServer/ServerRequestInfo.h
index 75705012037..30646626fc6 100644
--- a/TAO/tao/PortableServer/ServerRequestInfo.h
+++ b/TAO/tao/PortableServer/ServerRequestInfo.h
@@ -32,6 +32,9 @@
#include "tao/StringSeqC.h"
#include "tao/OctetSeqC.h"
#include "tao/Service_Context.h"
+
+//#include "PortableServerC.h"
+
#include "portableserver_export.h"
#if defined(_MSC_VER)
@@ -48,7 +51,7 @@ class TAO_PortableServer_Export TAO_ServerRequestInfo
: public virtual PortableInterceptor::ServerRequestInfo,
public virtual CORBA::LocalObject
{
- public:
+public:
TAO_ServerRequestInfo (TAO_ServerRequest &server_request);
virtual CORBA::ULong request_id (
@@ -195,8 +198,9 @@ protected:
CORBA::Object_var forward_reference_;
- CORBA::OctetSeq_var object_id_;
- CORBA::OctetSeq_var adapter_id_;
+ // PortableServer::Current_var poa_current_;
+ // CORBA::OctetSeq_var adapter_id_;
+
CORBA::Exception *caught_exception_;
PortableInterceptor::ReplyStatus reply_status_;
diff --git a/TAO/tao/Sequence.i b/TAO/tao/Sequence.i
index bd1078e1deb..e1fddfa3707 100644
--- a/TAO/tao/Sequence.i
+++ b/TAO/tao/Sequence.i
@@ -100,8 +100,38 @@ TAO_Unbounded_Base_Sequence::length (CORBA::ULong length)
{
if (length > this->maximum_)
{
- this->_allocate_buffer (length);
- this->maximum_ = length;
+ // At least double the size of the buffer each time the length
+ // is extended. This reduces the number of allocations, and
+ // copies accompanying those allocations signifantly for large
+ // numbers of small sequence length increases.
+ //
+ // Here is an example of the resulting buffer sizes during eigth
+ // iterations:
+ //
+ // desired length maximum allocation and copy
+ // -------------- ------- -------------------
+ // 1 1 yes
+ // 2 2 yes
+ // 3 4 yes
+ // 4 4 NO!
+ // 5 8 yes
+ // 6 8 NO!
+ // 7 8 NO!
+ // 8 8 NO!
+ //
+ // In this example, the number of allocations was reduced from 8
+ // to 4. Similarly, the number of copies was reduced from 28 to
+ // 7.
+
+ // Double the length. Notice that the left shift eventually
+ // causes "new_maximum" to potentially become less than
+ // "this->length_". This isn't a problem since the new maximum
+ // (and length) will just become "length".
+ CORBA::ULong new_maximum = this->length_ << 2;
+ new_maximum = (length > new_maximum ? length : new_maximum);
+
+ this->_allocate_buffer (new_maximum);
+ this->maximum_ = new_maximum;
this->release_ = 1;
}
else if (length < this->length_)
diff --git a/TAO/tao/operation_details.h b/TAO/tao/operation_details.h
index b66ddd9c272..e309804aab4 100644
--- a/TAO/tao/operation_details.h
+++ b/TAO/tao/operation_details.h
@@ -12,16 +12,18 @@
#ifndef TAO_OPERATION_DETAILS_H
#define TAO_OPERATION_DETAILS_H
+
#include "ace/pre.h"
-#include "tao/corbafwd.h"
+
+#include "corbafwd.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
-#include "tao/Service_Context.h"
-#include "tao/target_specification.h"
+#include "Service_Context.h"
+#include "target_specification.h"
// @@ Bala: Why is this not part of the RequestHeader?!
@@ -31,15 +33,16 @@
* @brief Class with operation details
*
* This class stores some of the "operation" details that would be
- * required by the invocation classes. this class is in its
- * infancy now but I expect this one to grow as we come with
+ * required by the invocation classes. This class is in its
+ * infancy now but I expect this one to grow as we come with
* different varieties of use cases.
*/
class TAO_Export TAO_Operation_Details
{
public:
- ///Ctor
+
+ ///Constructor
TAO_Operation_Details (const char *name,
CORBA::ULong len,
CORBA::Boolean argument_flag);
@@ -50,7 +53,7 @@ public:
/// Length of the operation name
CORBA::ULong opname_len (void) const;
- /// Return the flag that indicates whether the operation has any
+ /// Return the flag that indicates whether the operation has any
/// arguments
CORBA::Boolean argument_flag (void) const;
@@ -76,22 +79,22 @@ public:
void request_id (CORBA::ULong id);
/// Modify request id's for a BiDirectional setup
- void modify_request_id (int flag);
+ void modify_request_id (int originator);
- /// Get for request id
+ /// Return the request ID associated with the operation
CORBA::ULong request_id (void);
CORBA::ULong request_id (void) const;
- /// Get method for the addressing mode
+ /// Accessor method for the addressing mode
TAO_Target_Specification::TAO_Target_Address addressing_mode (void);
TAO_Target_Specification::TAO_Target_Address
addressing_mode (void) const;
/// Set method for the addressing mode
- void
- addressing_mode (CORBA::Short addr);
+ void addressing_mode (CORBA::Short addr);
private:
+
/// Name of the operation being invoked.
const char *opname_;
@@ -102,7 +105,7 @@ private:
CORBA::ULong request_id_;
/**
- * Flag that indicates whether the operation has any arguments. If
+ * Flag that indicates whether the operation has any arguments. If
* there are any arguments the flag will have a value of 1, 0
* otherwise.
*/
@@ -130,8 +133,9 @@ private:
};
#if defined (__ACE_INLINE__)
-# include "tao/operation_details.i"
+# include "operation_details.i"
#endif /* __ACE_INLINE__ */
#include "ace/post.h"
-#endif /*TAO_OPERATION_DETAILS_H*/
+
+#endif /* TAO_OPERATION_DETAILS_H */
diff --git a/TAO/tao/operation_details.i b/TAO/tao/operation_details.i
index c1e310eb713..5987b895223 100644
--- a/TAO/tao/operation_details.i
+++ b/TAO/tao/operation_details.i
@@ -1,17 +1,18 @@
// -*- C++ -*-
+//
//$Id$
+
ACE_INLINE
TAO_Operation_Details::TAO_Operation_Details (const char *name,
CORBA::ULong len,
CORBA::Boolean argument_flag)
- :opname_ (name),
- opname_len_ (len),
- request_id_ (0),
- argument_flag_ (argument_flag),
- response_flags_ (0),
- addressing_mode_ (TAO_Target_Specification::Key_Addr)
+ : opname_ (name),
+ opname_len_ (len),
+ request_id_ (0),
+ argument_flag_ (argument_flag),
+ response_flags_ (0),
+ addressing_mode_ (TAO_Target_Specification::Key_Addr)
{
- //no-op
}
ACE_INLINE const char*
@@ -91,14 +92,17 @@ TAO_Operation_Details::request_id (CORBA::ULong id)
}
ACE_INLINE void
-TAO_Operation_Details::modify_request_id (int flag)
+TAO_Operation_Details::modify_request_id (int originator)
{
- // If the flag value is -1 then BiDirectional connection has not
- // been negotiated
- if (flag >= 0)
- {
- this->request_id_ = (this->request_id_ * 2) + flag;
- }
+ // originator == 1 --> originating side
+ // originator == 0 --> other side
+ // originator == -1 --> no bi-directional connection was negotiated
+
+ // The originating side must have an even request ID, and the other
+ // side must have an odd request ID. Make sure that is the case.
+ if ((originator == 1 && ACE_ODD (this->request_id_))
+ || (originator == 0 && ACE_EVEN (this->request_id_)))
+ ++(this->request_id_);
}
ACE_INLINE CORBA::ULong
@@ -144,13 +148,12 @@ TAO_Operation_Details::addressing_mode (void) const
}
ACE_INLINE void
-TAO_Operation_Details::
- addressing_mode (CORBA::Short mode)
+TAO_Operation_Details::addressing_mode (CORBA::Short mode)
{
if (mode == 0)
- this->addressing_mode_ = TAO_Target_Specification::Key_Addr;
+ this->addressing_mode_ = TAO_Target_Specification::Key_Addr;
else if (mode == 1)
this->addressing_mode_ = TAO_Target_Specification::Profile_Addr;
else if (mode == 2)
- this->addressing_mode_ = TAO_Target_Specification::Reference_Addr;
+ this->addressing_mode_ = TAO_Target_Specification::Reference_Addr;
}