summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TAO/ChangeLog56
-rw-r--r--TAO/tao/IIOP_Profile.cpp28
-rw-r--r--TAO/tao/IIOP_Transport.cpp1
-rw-r--r--TAO/tao/Makefile.tao4
-rw-r--r--TAO/tao/ORB_Core.cpp26
-rw-r--r--TAO/tao/ORB_Core.h7
-rw-r--r--TAO/tao/ORB_Core.i6
-rw-r--r--TAO/tao/ObjectKey_Table.cpp169
-rw-r--r--TAO/tao/ObjectKey_Table.h125
-rw-r--r--TAO/tao/Profile.cpp44
-rw-r--r--TAO/tao/Profile.h12
-rw-r--r--TAO/tao/Profile.i2
-rw-r--r--TAO/tao/Refcounted_ObjectKey.cpp23
-rw-r--r--TAO/tao/Refcounted_ObjectKey.h68
-rw-r--r--TAO/tao/Refcounted_ObjectKey.inl26
-rw-r--r--TAO/tao/Resource_Factory.cpp6
-rw-r--r--TAO/tao/Resource_Factory.h3
-rw-r--r--TAO/tao/Strategies/DIOP_Profile.cpp28
-rw-r--r--TAO/tao/Strategies/SHMIOP_Profile.cpp29
-rw-r--r--TAO/tao/Strategies/UIOP_Profile.cpp28
-rw-r--r--TAO/tao/default_resource.cpp41
-rw-r--r--TAO/tao/default_resource.h4
22 files changed, 674 insertions, 62 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index 648a8544250..a6ffb9ed6cd 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,59 @@
+Sun May 11 10:44:56 2003 Balachandran Natarajan <bala@dre.vanderbilt.edu>
+
+ The aim of this checkin is to reduce the runtime memory consumed
+ by the IORs. Every profile held by the ORB had a copy of the
+ ObjectKey which added to the memory consumed by the IORs. This
+ checkin builds a map to store and access the object key
+ efficiently.
+
+ * tao/ObjectKey_Table.cpp:
+ * tao/ObjectKey_Table.h: Class that builds a map to store the
+ object key.
+
+ * tao/Refcounted_ObjectKey.cpp:
+ * tao/Refcounted_ObjectKey.h:
+ * tao/Refcounted_ObjectKey.inl: A wrapper class for the object key
+ that provides reference counting and automatic lifetime
+ management to the object keys.
+
+ * tao/Profile.cpp:
+ * tao/Profile.h:
+ * tao/Profile.i: Have a pointer to the refcounted object key
+ instead of the actual object key. After unmarshalling the
+ object key from the profile we now bind it with the ObjectKey
+ table which returns a pointer to the refcounted object key
+ which is cached and used during invocation.
+
+ * tao/IIOP_Profile.cpp:
+ * tao/Strategies/DIOP_Profile.cpp:
+ * tao/Strategies/SHMIOP_Profile.cpp:
+ * tao/Strategies/UIOP_Profile.cpp: Use the refcounted object key
+ pointer instead of object keys.
+
+ * tao/IIOP_Transport.cpp: Removed gratuitious inclusion of the
+ Stub.h.
+
+ * tao/ORB_Core.cpp:
+ * tao/ORB_Core.h:
+ * tao/ORB_Core.i: ObjectKey_Table would now be a member of the
+ ORB_Core class, initialized during the init () call and
+ destroyed during TAO_ORB_Core::fini (). This class also provides
+ an accessor for accessing the ObjectKey_Table.
+
+ * tao/Resource_Factory.cpp:
+ * tao/Resource_Factory.h: Added a virtual method
+ create_object_key_table_lock () that helps in creating the right
+ type of lock for the ObjectKey_Table.
+
+ * tao/default_resource.cpp:
+ * tao/default_resource.h: Implementation for
+ create_object_key_table_lock ().
+
+ Added an option -ORBObjectKeyTableLock that helps the user to
+ configure the type of lock used.
+
+ * tao/Makefile.tao: Added the new files into the Makefile.
+
Sun May 11 10:37:56 2003 Nanbor Wang <nanbor@cs.wustl.edu>
Checked in updates that sat in my workspace for a long time.
diff --git a/TAO/tao/IIOP_Profile.cpp b/TAO/tao/IIOP_Profile.cpp
index 8bd9333d8b1..62c8f740edf 100644
--- a/TAO/tao/IIOP_Profile.cpp
+++ b/TAO/tao/IIOP_Profile.cpp
@@ -198,7 +198,10 @@ TAO_IIOP_Profile::parse_string_i (const char *ior
this->endpoint_.host_ = CORBA::string_dup (tmp_host);
}
- TAO::ObjectKey::decode_string_to_sequence (this->object_key_, okd + 1);
+ TAO::ObjectKey &ok = ACE_const_cast (TAO::ObjectKey&,
+ this->ref_object_key_->object_key ());
+ TAO::ObjectKey::decode_string_to_sequence (ok,
+ okd + 1);
}
CORBA::Boolean
@@ -212,7 +215,8 @@ TAO_IIOP_Profile::is_equivalent (const TAO_Profile *other_profile)
ACE_dynamic_cast (const TAO_IIOP_Profile *, other_profile);
- if (!(this->object_key_ == op->object_key_
+ if (!(this->ref_object_key_->object_key () ==
+ op->ref_object_key_->object_key ()
&& this->version_ == op->version_
&& this->count_ == op->count_))
return 0;
@@ -248,10 +252,13 @@ TAO_IIOP_Profile::hash (CORBA::ULong max
hashval += this->version_.minor;
hashval += this->tag ();
- if (this->object_key_.length () >= 4)
+ const TAO::ObjectKey &ok =
+ this->ref_object_key_->object_key ();
+
+ if (ok.length () >= 4)
{
- hashval += this->object_key_ [1];
- hashval += this->object_key_ [3];
+ hashval += ok[1];
+ hashval += ok[3];
}
return hashval % max;
@@ -283,7 +290,7 @@ TAO_IIOP_Profile::to_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
- this->object_key_);
+ this->ref_object_key_->object_key ());
size_t buflen = (8 /* "corbaloc" */ +
1 /* colon separator */ +
@@ -338,7 +345,14 @@ TAO_IIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
encap.write_ushort (this->endpoint_.port ());
// OCTET SEQUENCE for object key
- encap << this->object_key_;
+ if (this->ref_object_key_)
+ encap << this->ref_object_key_->object_key ();
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) TAO - IIOP_Profile::create_profile_body ",
+ "no object key marshalled \n"));
+ }
if (this->version_.major > 1
|| this->version_.minor > 0)
diff --git a/TAO/tao/IIOP_Transport.cpp b/TAO/tao/IIOP_Transport.cpp
index 95a3d7b4c6a..69a1f2acab9 100644
--- a/TAO/tao/IIOP_Transport.cpp
+++ b/TAO/tao/IIOP_Transport.cpp
@@ -10,7 +10,6 @@
#include "Transport_Mux_Strategy.h"
#include "Wait_Strategy.h"
#include "Sync_Strategies.h"
-#include "Stub.h"
#include "ORB_Core.h"
#include "debug.h"
#include "GIOP_Message_Base.h"
diff --git a/TAO/tao/Makefile.tao b/TAO/tao/Makefile.tao
index 006c88d3185..d364774a214 100644
--- a/TAO/tao/Makefile.tao
+++ b/TAO/tao/Makefile.tao
@@ -296,7 +296,9 @@ ORB_CORE_FILES = \
Default_Thread_Lane_Resources_Manager \
Default_Stub_Factory \
Request_Dispatcher \
- Valuetype_Adapter
+ Valuetype_Adapter \
+ ObjectKey_Table \
+ Refcounted_ObjectKey
DYNAMIC_ANY_FILES =
diff --git a/TAO/tao/ORB_Core.cpp b/TAO/tao/ORB_Core.cpp
index b68e3484258..13a08daa3f9 100644
--- a/TAO/tao/ORB_Core.cpp
+++ b/TAO/tao/ORB_Core.cpp
@@ -142,14 +142,9 @@ TAO_ORB_Core::TAO_ORB_Core (const char *orbid)
orb_params_ (),
init_ref_map_ (TAO_DEFAULT_OBJECT_REF_TABLE_SIZE),
object_ref_table_ (),
+ object_key_table_ (),
orbid_ (ACE_OS::strdup (orbid ? orbid : "")),
resource_factory_ (0),
-#if 0
- /// @@todo:Need to go one day
- message_block_dblock_allocator_ (0),
- message_block_buffer_allocator_ (0),
- message_block_msgblock_allocator_ (0),
-#endif /*if 0*/
// server_id_ (0),
client_factory_ (0),
server_factory_ (0),
@@ -923,6 +918,9 @@ TAO_ORB_Core::init (int &argc, char *argv[] ACE_ENV_ARG_DECL)
ssf->open (this);
+ // Open the ObjectKey_Table
+ (void) this->object_key_table_.init (this);
+
// Obtain the timeout value for the thread-per-connection model
this->thread_per_connection_use_timeout_ =
ssf->thread_per_connection_timeout (this->thread_per_connection_timeout_);
@@ -1123,20 +1121,8 @@ TAO_ORB_Core::fini (void)
(void) TAO_Internal::close_services ();
-#if 0
- // @@todo: Need to go someday!
- if (this->message_block_dblock_allocator_)
- this->message_block_dblock_allocator_->remove ();
- delete this->message_block_dblock_allocator_;
-
- if (this-> message_block_buffer_allocator_)
- this->message_block_buffer_allocator_->remove ();
- delete this->message_block_buffer_allocator_;
-
- if (this->message_block_msgblock_allocator_)
- this->message_block_msgblock_allocator_->remove ();
- delete this->message_block_msgblock_allocator_;
-#endif /*if 0*/
+ // Destroy the object_key table
+ this->object_key_table_.destroy ();
delete this;
diff --git a/TAO/tao/ORB_Core.h b/TAO/tao/ORB_Core.h
index 50db8476681..39fe569890d 100644
--- a/TAO/tao/ORB_Core.h
+++ b/TAO/tao/ORB_Core.h
@@ -35,6 +35,7 @@
#include "Fault_Tolerance_Service.h"
#include "Cleanup_Func_Registry.h"
#include "Object_Ref_Table.h"
+#include "ObjectKey_Table.h"
// Interceptor definitions.
#include "PortableInterceptorC.h"
@@ -922,6 +923,9 @@ public:
/// the resolve_initial_references() mechanism.
TAO_Object_Ref_Table &object_ref_table (void);
+ /// Acceessor to the table that stores the object_keys.
+ TAO::ObjectKey_Table &object_key_table (void);
+
/// Return the current request dispatcher strategy.
TAO_Request_Dispatcher *request_dispatcher (void);
@@ -1096,6 +1100,9 @@ protected:
/// resolve_initial_references() mechanism.
TAO_Object_Ref_Table object_ref_table_;
+ /// Table that stores the object key instead of caching one per-profile.
+ TAO::ObjectKey_Table object_key_table_;
+
/// The ORBid for this ORB.
char *orbid_;
diff --git a/TAO/tao/ORB_Core.i b/TAO/tao/ORB_Core.i
index 0bc65fe7e2b..b5fc98a3ccd 100644
--- a/TAO/tao/ORB_Core.i
+++ b/TAO/tao/ORB_Core.i
@@ -50,6 +50,12 @@ TAO_ORB_Core::object_ref_table (void)
return this->object_ref_table_;
}
+ACE_INLINE TAO::ObjectKey_Table &
+TAO_ORB_Core::object_key_table (void)
+{
+ return this->object_key_table_;
+}
+
ACE_INLINE TAO_Flushing_Strategy *
TAO_ORB_Core::flushing_strategy (void)
{
diff --git a/TAO/tao/ObjectKey_Table.cpp b/TAO/tao/ObjectKey_Table.cpp
new file mode 100644
index 00000000000..7013bc4e620
--- /dev/null
+++ b/TAO/tao/ObjectKey_Table.cpp
@@ -0,0 +1,169 @@
+//$Id$
+#include "ObjectKey_Table.h"
+#include "ORB_Core.h"
+#include "Refcounted_ObjectKey.h"
+
+ACE_RCSID(tao,
+ ObjectKey_Table,
+ "$Id$")
+
+
+TAO::ObjectKey_Table::ObjectKey_Table (void)
+ : lock_ (0)
+ , table_ ()
+{
+
+}
+
+TAO::ObjectKey_Table::~ObjectKey_Table (void)
+{
+ this->table_.close ();
+ delete this->lock_;
+}
+
+int
+TAO::ObjectKey_Table::init (TAO_ORB_Core *oc)
+{
+ /// Create the lock that is needed for internal usage.
+ this->lock_ =
+ oc->resource_factory ()->create_object_key_table_lock ();
+
+ return 0;
+}
+
+int
+TAO::ObjectKey_Table::bind (const TAO::ObjectKey &key,
+ TAO::Refcounted_ObjectKey *&key_new)
+
+{
+ key_new = 0;
+
+ // NOTE:Place for optimization. This is real expensive..
+ CORBA::String_var str;
+ TAO::ObjectKey::encode_sequence_to_string (str.inout (),
+ key);
+
+ // Hash values can be tricky, but even then thy are useful at
+ // times.
+ u_long hash_val =
+ ACE::hash_pjw (str.in ());
+
+ int retval = 0;
+ {
+ ACE_GUARD_RETURN (ACE_Lock,
+ ace_mon,
+ *this->lock_,
+ 0);
+
+ // This is a tradeoff.. We could avoid this two stage process of
+ // using a find () and then a bind () , which would make things
+ // efficient. BUT we may have to do allocation upfront and delete if
+ // bind () returns with an entry. We take one of the routes that
+ // avoids allocation.
+ retval = this->table_.find (hash_val,
+ key_new);
+
+ if (retval == -1)
+ return this->bind_i (hash_val,
+ key,
+ key_new);
+
+
+ // Do a sanity comparison check and increment the refcount.
+ // Place for optimization by removing the comparison.
+ if (key_new->object_key () == key)
+ {
+ (void) key_new->incr_refcount ();
+ }
+ else
+ {
+ // Do we bind it again. And if so, how?
+ // Need to thinkk....
+ }
+ }
+
+ return 0;
+}
+
+int
+TAO::ObjectKey_Table::unbind (TAO::Refcounted_ObjectKey *&key_new)
+
+{
+ ACE_GUARD_RETURN (ACE_Lock,
+ ace_mon,
+ *this->lock_,
+ 0);
+ // If the refcount has dropped to 1, just go ahead and unbind it
+ // from the table.
+ if (key_new->decr_refcount () == 1)
+ return this->unbind_i (key_new);
+
+ return 0;
+}
+
+int
+TAO::ObjectKey_Table::destroy (void)
+{
+ if (this->table_.current_size ())
+ {
+ ACE_GUARD_RETURN (ACE_Lock,
+ ace_mon,
+ *this->lock_,
+ 0);
+
+ TABLE::ITERATOR end_iter = this->table_.end ();
+
+ for (TABLE::ITERATOR start = this->table_.begin ();
+ start != end_iter;
+ ++start)
+ {
+ TABLE::ENTRY &ent = (*start);
+
+ (void) ent.item ()->decr_refcount ();
+
+ this->table_.unbind (&ent);
+ }
+ }
+
+ return 0;
+}
+
+int
+TAO::ObjectKey_Table::bind_i (u_long hash_val,
+ const TAO::ObjectKey &key,
+ TAO::Refcounted_ObjectKey *&key_new)
+{
+ ACE_NEW_RETURN (key_new,
+ TAO::Refcounted_ObjectKey (key),
+ -1);
+
+ int retval = this->table_.bind (hash_val,
+ key_new);
+
+ if (retval != -1)
+ key_new->incr_refcount ();
+ else
+ key_new->decr_refcount ();
+
+ return retval;
+}
+
+int
+TAO::ObjectKey_Table::unbind_i (TAO::Refcounted_ObjectKey *&key_new)
+{
+ // NOTE:Place for optimization. This is real expensive..
+ CORBA::String_var str;
+ TAO::ObjectKey::encode_sequence_to_string (str.inout (),
+ key_new->object_key ());
+
+ u_long hash_val =
+ ACE::hash_pjw (str.in ());
+
+ (void) this->table_.unbind (hash_val,
+ key_new);
+
+ // Remove our refcount on the ObjectKey
+ (void) key_new->decr_refcount ();
+
+ return 0;
+}
diff --git a/TAO/tao/ObjectKey_Table.h b/TAO/tao/ObjectKey_Table.h
new file mode 100644
index 00000000000..52ded9b5294
--- /dev/null
+++ b/TAO/tao/ObjectKey_Table.h
@@ -0,0 +1,125 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ObjectKey_Table.h
+ *
+ * $Id$
+ *
+ * @author Balachandran Natarajan <bala@dre.vanderbilt.edu>
+ */
+//=============================================================================
+#ifndef TAO_OBJECTKEY_TABLE_H
+#define TAO_OBJECTKEY_TABLE_H
+#include "ace/pre.h"
+#include "ace/RB_Tree.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/TAO_Export.h"
+
+
+// Forward declarations
+class TAO_ORB_Core;
+
+
+namespace TAO
+{
+
+ // Forward declarations within the namespace..
+
+ class ObjectKey;
+ class Refcounted_ObjectKey;
+
+ /**
+ * @class ObjectKey_Table
+ *
+ * @brief Table that maintains the set of ObjectKey's seen by the
+ * ORB.
+ *
+ * The ORB maintains one table for the whole ORB. ObjectKeys
+ * generated by the ORB or the ones seen by the ORB from remote
+ * ORB's are stored here. The ObjectKeys are stored through a
+ * wrapper which encapsulates the refcount on them. This class
+ * actually provides the synchronization mechanism for manipulating
+ * the reference counts on the object keys provided by the wrapper
+ * class.
+ *
+ * This class does not offer a find () call with a reason. The call
+ * to bind () will return a pointer which is expected to be cached
+ * by the client/caller and use the pointer in every invocation.
+ *
+ * @NOTE: This class uses the ACE_RB_Tree to maintain the table of
+ * ObjectKeys. The RB_Tree has good insertion and lookup
+ * properties. Its Iteration properties are not that good, but we
+ * dont need to do much iteration unless we are closing down the
+ * table.
+ *
+ * @NOTE: The reasons to use RB_Tree are its good dynamic
+ * properties. We should try to strategize the class to use either a
+ * Hash_Map or a RB_Tree based on some runtime option. For that we
+ * need an adapter class in ACE, like an ACE_Lock_Adapter class. We
+ * will do that if our instrumentation shows the need for it.
+ *
+ */
+ class TAO_Export ObjectKey_Table
+ {
+ public:
+ /// Default Constructor and destructor..
+ ObjectKey_Table (void);
+
+ ~ObjectKey_Table (void);
+
+ /// Initialize method that sets up the underlying lock and other
+ /// related stuff.
+ int init (TAO_ORB_Core *orb);
+
+ /// Iterates and unbinds the contents of the table.
+ int destroy (void);
+
+ /// Bind the ObjectKey in the table.
+ /**
+ * Bind an ObjectKey in the table and return a pointer to the
+ * Refcounted_ObjectKey which the client can use. If the ObjectKey
+ * is already available in the table, this operation just
+ * increments the refcount on the ObjectKey. If the ObjectKey is
+ * new it is bounded to the table. Returns a 0 on success and a -1
+ * on failure.
+ */
+ int bind (const ObjectKey &key,
+ Refcounted_ObjectKey *&key_new);
+
+ /// Unbind an ObjectKey from the table.
+ int unbind (TAO::Refcounted_ObjectKey *&key);
+
+ protected:
+ /// Implementation for bind ().
+ int bind_i (u_long hash_val,
+ const ObjectKey &key,
+ Refcounted_ObjectKey *&key_new);
+
+ /// Implementation for unbind ().
+ int unbind_i (Refcounted_ObjectKey *&key);
+
+ private:
+
+ // Some useful typedefs.
+ typedef unsigned long ExtId;
+
+ typedef ACE_RB_Tree<ExtId,
+ TAO::Refcounted_ObjectKey *,
+ ACE_Less_Than <ExtId>,
+ ACE_Null_Mutex> TABLE;
+
+ /// Lock for the table.
+ ACE_Lock *lock_;
+
+ /// Table that contains the data
+ TABLE table_;
+ };
+}
+
+#include "ace/post.h"
+#endif /*TAO_OBJECT_KEY_TABLE_H*/
diff --git a/TAO/tao/Profile.cpp b/TAO/tao/Profile.cpp
index 341efa8f02d..69ab21cdd43 100644
--- a/TAO/tao/Profile.cpp
+++ b/TAO/tao/Profile.cpp
@@ -6,6 +6,8 @@
#include "Stub.h"
#include "debug.h"
#include "target_specification.h"
+#include "Object_KeyC.h"
+#include "ORB_Core.h"
#include "ace/CDR_Base.h"
#if !defined (__ACE_INLINE__)
@@ -27,12 +29,14 @@ TAO_Profile::TAO_Profile (CORBA::ULong tag,
, policy_list_ (0)
, addressing_mode_ (0)
, tagged_profile_ (0)
- , object_key_ (obj_key)
+ , ref_object_key_ (0)
, tag_ (tag)
, orb_core_ (orb_core)
, forward_to_ (0)
, refcount_ (1)
{
+ (void) this->orb_core_->object_key_table ().bind (obj_key,
+ this->ref_object_key_);
}
TAO_Profile::TAO_Profile (CORBA::ULong tag,
@@ -44,7 +48,7 @@ TAO_Profile::TAO_Profile (CORBA::ULong tag,
, policy_list_ (0)
, addressing_mode_ (0)
, tagged_profile_ (0)
- , object_key_ ()
+ , ref_object_key_ (0)
, tag_ (tag)
, orb_core_ (orb_core)
, forward_to_ (0)
@@ -56,6 +60,8 @@ TAO_Profile::~TAO_Profile (void)
{
if (this->tagged_profile_)
delete this->tagged_profile_;
+
+ this->orb_core_->object_key_table ().unbind (this->ref_object_key_);
}
CORBA::ULong
@@ -107,10 +113,12 @@ TAO_Profile::_key (void) const
{
TAO::ObjectKey *key = 0;
- ACE_NEW_RETURN (key,
- TAO::ObjectKey (this->object_key_),
- 0);
-
+ if (this->ref_object_key_)
+ {
+ ACE_NEW_RETURN (key,
+ TAO::ObjectKey (this->ref_object_key_->object_key ()),
+ 0);
+ }
return key;
}
@@ -166,8 +174,30 @@ TAO_Profile::decode (TAO_InputCDR& cdr)
if (this->decode_profile (cdr) < 0)
return -1;
+ // @@NOTE: This place *may* need strategizing. Here are the
+ // issues. Placing the ObjectKey in the table adds an allocation and
+ // a lock while decoding. This is bad for some cases especially if
+ // the application is marshalling object references across to the
+ // server end. But the server could use "lazy" evaluation and avoid
+ // this during marshalling.
+ //
+ // The only place this will get important is when a thead tries to
+ // use the object reference to create a CORBA object to make an
+ // invocation. Since creation of a CORBA object itself is expensive,
+ // it looks like we may not need to worry much.
+ //
+ // Remember strategizing needs reconciliation of forces imposed
+ // by runtime memory growth. Doing a random strategization would
+ // destroy the wins in runtime memory growth got by using this
+ // table scheme.
+ TAO::ObjectKey ok;
+
// ... and object key.
- if ((cdr >> this->object_key_) == 0)
+ if ((cdr >> ok) == 0)
+ return -1;
+
+ if (this->orb_core ()->object_key_table ().bind (ok,
+ this->ref_object_key_) == -1)
return -1;
// Tagged Components *only* exist after version 1.0!
diff --git a/TAO/tao/Profile.h b/TAO/tao/Profile.h
index c5cce5ef180..f512f55b8ef 100644
--- a/TAO/tao/Profile.h
+++ b/TAO/tao/Profile.h
@@ -20,22 +20,26 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "tao/GIOP_Message_Version.h"
-#include "tao/Object_KeyC.h"
-
-
#include "ace/Synch.h"
+#include "tao/Refcounted_ObjectKey.h"
class TAO_MProfile;
class TAO_Stub;
class TAO_Endpoint;
class TAO_ORB_Core;
+
/// Forward declaration of PolicyList
namespace CORBA
{
class PolicyList;
}
+namespace TAO
+{
+ class Refcounted_ObjectKey;
+}
+
/**
* @class TAO_Profile
*
@@ -309,7 +313,7 @@ protected:
IOP::TaggedProfile *tagged_profile_;
/// object_key associated with this profile.
- TAO::ObjectKey object_key_;
+ TAO::Refcounted_ObjectKey *ref_object_key_;
private:
/// IOP protocol tag.
diff --git a/TAO/tao/Profile.i b/TAO/tao/Profile.i
index af9ff0b4b14..dde1611c1da 100644
--- a/TAO/tao/Profile.i
+++ b/TAO/tao/Profile.i
@@ -58,5 +58,5 @@ TAO_Profile::addressing_mode (void) const
ACE_INLINE const TAO::ObjectKey &
TAO_Profile::object_key (void) const
{
- return this->object_key_;
+ return this->ref_object_key_->object_key ();
}
diff --git a/TAO/tao/Refcounted_ObjectKey.cpp b/TAO/tao/Refcounted_ObjectKey.cpp
new file mode 100644
index 00000000000..b2cd277b7e0
--- /dev/null
+++ b/TAO/tao/Refcounted_ObjectKey.cpp
@@ -0,0 +1,23 @@
+//$Id$
+#include "Refcounted_ObjectKey.h"
+
+
+#if !defined (__ACE_INLINE__)
+#include "Refcounted_ObjectKey.inl"
+#endif /* defined INLINE */
+
+ACE_RCSID(tao,
+ Refcounted_ObjectKey,
+ "$Id$")
+
+
+TAO::Refcounted_ObjectKey::Refcounted_ObjectKey (const TAO::ObjectKey &key)
+ : object_key_ (key)
+ , ref_count_ (1)
+{
+}
+
+
+TAO::Refcounted_ObjectKey::~Refcounted_ObjectKey (void)
+{
+}
diff --git a/TAO/tao/Refcounted_ObjectKey.h b/TAO/tao/Refcounted_ObjectKey.h
new file mode 100644
index 00000000000..deaae1841ba
--- /dev/null
+++ b/TAO/tao/Refcounted_ObjectKey.h
@@ -0,0 +1,68 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Refcounted_ObjectKey.h
+ *
+ * $Id$
+ *
+ * @author Balachandran Natarajan <bala@dre.vanderbilt.edu>
+ */
+//=============================================================================
+#ifndef TAO_REFCOUNTED_OBJECTKEY_H
+#define TAO_REFCOUNTED_OBJECTKEY_H
+#include "ace/pre.h"
+
+#include "tao/Object_KeyC.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+namespace TAO
+{
+ /**
+ * @class Refcounted_ObjectKey
+ *
+ * @brief A wrapper class that ties together a refcount to an
+ * ObjectKey.
+ *
+ * The refounts in this class is manipulated within the context of
+ * the lock in the TAO::ObjectKey_Table. Manipulating the refcounts
+ * from anywhere else is strictly forbidden.
+ */
+ class TAO_Export Refcounted_ObjectKey
+ {
+ public:
+ /// Constructor
+ Refcounted_ObjectKey (const ObjectKey &ref);
+
+ /// Accessor for the underlying ObjectKey.
+ const ObjectKey &object_key (void) const;
+
+ protected:
+ friend class ObjectKey_Table;
+
+ /// Protected destructor
+ ~Refcounted_ObjectKey (void);
+
+ /// Methods for incrementing and decrementing refcounts.
+ long incr_refcount (void);
+ long decr_refcount (void);
+
+ private:
+ /// The object key
+ ObjectKey object_key_;
+
+ /// The refcount on the object key..
+ long ref_count_;
+ };
+
+}
+
+#if defined (__ACE_INLINE__)
+#include "Refcounted_ObjectKey.inl"
+#endif /* defined INLINE */
+
+#include "ace/post.h"
+#endif /*TAO_REFCOUNTED_OBJECTKEY_H*/
diff --git a/TAO/tao/Refcounted_ObjectKey.inl b/TAO/tao/Refcounted_ObjectKey.inl
new file mode 100644
index 00000000000..eccd955c4bb
--- /dev/null
+++ b/TAO/tao/Refcounted_ObjectKey.inl
@@ -0,0 +1,26 @@
+// -*- C++ -*-
+// $Id$
+ACE_INLINE long
+TAO::Refcounted_ObjectKey::incr_refcount (void)
+{
+ return ++this->ref_count_;
+}
+
+ACE_INLINE long
+TAO::Refcounted_ObjectKey::decr_refcount (void)
+{
+ if (--this->ref_count_ > 0)
+ return this->ref_count_;
+
+ ACE_ASSERT (this->ref_count_ == 0);
+
+ delete this;
+
+ return 0;
+}
+
+ACE_INLINE const TAO::ObjectKey &
+TAO::Refcounted_ObjectKey::object_key (void) const
+{
+ return this->object_key_;
+}
diff --git a/TAO/tao/Resource_Factory.cpp b/TAO/tao/Resource_Factory.cpp
index 44063c904a0..86daf405582 100644
--- a/TAO/tao/Resource_Factory.cpp
+++ b/TAO/tao/Resource_Factory.cpp
@@ -195,6 +195,12 @@ TAO_Resource_Factory::locked_transport_cache (void)
}
ACE_Lock *
+TAO_Resource_Factory::create_object_key_table_lock (void)
+{
+ return 0;
+}
+
+ACE_Lock *
TAO_Resource_Factory::create_corba_object_lock (void)
{
return 0;
diff --git a/TAO/tao/Resource_Factory.h b/TAO/tao/Resource_Factory.h
index b21e627a30c..46a2c30a67b 100644
--- a/TAO/tao/Resource_Factory.h
+++ b/TAO/tao/Resource_Factory.h
@@ -202,6 +202,9 @@ public:
/// transport cache needs to be locked else return 0
virtual int locked_transport_cache (void);
+ /// Creates a lock needed for the table that stores the object keys.
+ virtual ACE_Lock *create_object_key_table_lock (void);
+
/// Creates the lock for the CORBA Object
virtual ACE_Lock *create_corba_object_lock (void);
diff --git a/TAO/tao/Strategies/DIOP_Profile.cpp b/TAO/tao/Strategies/DIOP_Profile.cpp
index e99db319aa7..73cb6167905 100644
--- a/TAO/tao/Strategies/DIOP_Profile.cpp
+++ b/TAO/tao/Strategies/DIOP_Profile.cpp
@@ -208,7 +208,10 @@ TAO_DIOP_Profile::parse_string_i (const char *ior
this->endpoint_.host_ = CORBA::string_dup (tmp_host);
}
- TAO::ObjectKey::decode_string_to_sequence (this->object_key_, okd + 1);
+ TAO::ObjectKey &ok = ACE_const_cast (TAO::ObjectKey&,
+ this->ref_object_key_->object_key ());
+ TAO::ObjectKey::decode_string_to_sequence (ok,
+ okd + 1);
}
CORBA::Boolean
@@ -222,7 +225,8 @@ TAO_DIOP_Profile::is_equivalent (const TAO_Profile *other_profile)
ACE_dynamic_cast (const TAO_DIOP_Profile *, other_profile);
- if (!(this->object_key_ == op->object_key_
+ if (!(this->ref_object_key_->object_key () ==
+ op->ref_object_key_->object_key ()
&& this->version_ == op->version_
&& this->count_ == op->count_))
return 0;
@@ -258,10 +262,13 @@ TAO_DIOP_Profile::hash (CORBA::ULong max
hashval += this->version_.minor;
hashval += this->tag ();
- if (this->object_key_.length () >= 4)
+ const TAO::ObjectKey &ok =
+ this->ref_object_key_->object_key ();
+
+ if (ok.length () >= 4)
{
- hashval += this->object_key_ [1];
- hashval += this->object_key_ [3];
+ hashval += ok[1];
+ hashval += ok[3];
}
return hashval % max;
@@ -293,7 +300,7 @@ TAO_DIOP_Profile::to_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
- this->object_key_);
+ this->ref_object_key_->object_key ());
size_t buflen = (8 /* "corbaloc" */ +
1 /* colon separator */ +
@@ -348,7 +355,14 @@ TAO_DIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
encap.write_ushort (this->endpoint_.port ());
// OCTET SEQUENCE for object key
- encap << this->object_key_;
+ if (this->ref_object_key_)
+ encap << this->ref_object_key_->object_key ();
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) TAO - UIOP_Profile::create_profile_body ",
+ "no object key marshalled \n"));
+ }
if (this->version_.major > 1
|| this->version_.minor > 0)
diff --git a/TAO/tao/Strategies/SHMIOP_Profile.cpp b/TAO/tao/Strategies/SHMIOP_Profile.cpp
index fb9b5691ee7..6202344b417 100644
--- a/TAO/tao/Strategies/SHMIOP_Profile.cpp
+++ b/TAO/tao/Strategies/SHMIOP_Profile.cpp
@@ -236,7 +236,11 @@ TAO_SHMIOP_Profile::parse_string_i (const char *string
start = ++okd; // increment past the object key separator
- TAO::ObjectKey::decode_string_to_sequence (this->object_key_, start);
+ TAO::ObjectKey &ok = ACE_const_cast (TAO::ObjectKey&,
+ this->ref_object_key_->object_key ());
+
+ TAO::ObjectKey::decode_string_to_sequence (ok,
+ start);
}
CORBA::Boolean
@@ -249,7 +253,8 @@ TAO_SHMIOP_Profile::is_equivalent (const TAO_Profile *other_profile)
const TAO_SHMIOP_Profile *op =
ACE_dynamic_cast (const TAO_SHMIOP_Profile *, other_profile);
- if (!(this->object_key_ == op->object_key_
+ if (!(this->ref_object_key_->object_key () ==
+ op->ref_object_key_->object_key ()
&& this->version_ == op->version_
&& this->count_ == op->count_))
return 0;
@@ -285,10 +290,13 @@ TAO_SHMIOP_Profile::hash (CORBA::ULong max
hashval += this->version_.minor;
hashval += this->tag ();
- if (this->object_key_.length () >= 4)
+ const TAO::ObjectKey &ok =
+ this->ref_object_key_->object_key ();
+
+ if (ok.length () >= 4)
{
- hashval += this->object_key_ [1];
- hashval += this->object_key_ [3];
+ hashval += ok[1];
+ hashval += ok[3];
}
return hashval % max;
@@ -308,7 +316,7 @@ TAO_SHMIOP_Profile::to_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
- this->object_key_);
+ this->ref_object_key_->object_key ());
size_t buflen = (8 /* corbaloc */ +
1 /* colon separator */ +
@@ -362,7 +370,14 @@ TAO_SHMIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
encap.write_ushort (this->endpoint_.port ());
// OCTET SEQUENCE for object key
- encap << this->object_key_;
+ if (this->ref_object_key_)
+ encap << this->ref_object_key_->object_key ();
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) TAO - UIOP_Profile::create_profile_body ",
+ "no object key marshalled \n"));
+ }
if (this->version_.major > 1
|| this->version_.minor > 0)
diff --git a/TAO/tao/Strategies/UIOP_Profile.cpp b/TAO/tao/Strategies/UIOP_Profile.cpp
index 8f8c8dacbdb..1613ac9e204 100644
--- a/TAO/tao/Strategies/UIOP_Profile.cpp
+++ b/TAO/tao/Strategies/UIOP_Profile.cpp
@@ -133,7 +133,10 @@ TAO_UIOP_Profile::parse_string_i (const char *string
start = ++cp; // increment past the object key separator
- TAO::ObjectKey::decode_string_to_sequence (this->object_key_, start);
+ TAO::ObjectKey &ok = ACE_const_cast (TAO::ObjectKey&,
+ this->ref_object_key_->object_key ());
+ TAO::ObjectKey::decode_string_to_sequence (ok,
+ start);
}
CORBA::Boolean
@@ -146,7 +149,8 @@ TAO_UIOP_Profile::is_equivalent (const TAO_Profile *other_profile)
const TAO_UIOP_Profile *op =
ACE_dynamic_cast (const TAO_UIOP_Profile *, other_profile);
- if (!(this->object_key_ == op->object_key_
+ if (!(this->ref_object_key_->object_key () ==
+ op->ref_object_key_->object_key ()
&& this->version_ == op->version_
&& this->count_ == op->count_))
return 0;
@@ -182,10 +186,13 @@ TAO_UIOP_Profile::hash (CORBA::ULong max
hashval += this->version_.minor;
hashval += this->tag ();
- if (this->object_key_.length () >= 4)
+ const TAO::ObjectKey &ok =
+ this->ref_object_key_->object_key ();
+
+ if (ok.length () >= 4)
{
- hashval += this->object_key_ [1];
- hashval += this->object_key_ [3];
+ hashval += ok[1];
+ hashval += ok[3];
}
return hashval % max;
@@ -206,7 +213,7 @@ TAO_UIOP_Profile::to_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
- this->object_key_);
+ this->ref_object_key_->object_key ());
u_int buflen = (8 /* "corbaloc" */ +
1 /* colon separator */ +
@@ -289,7 +296,14 @@ TAO_UIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
encap.write_string (this->endpoint_.rendezvous_point ());
// OCTET SEQUENCE for object key
- encap << this->object_key_;
+ if (this->ref_object_key_)
+ encap << this->ref_object_key_->object_key ();
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) TAO - UIOP_Profile::create_profile_body ",
+ "no object key marshalled \n"));
+ }
if (this->version_.major > 1
|| this->version_.minor > 0)
diff --git a/TAO/tao/default_resource.cpp b/TAO/tao/default_resource.cpp
index 430008e9902..8c759dac768 100644
--- a/TAO/tao/default_resource.cpp
+++ b/TAO/tao/default_resource.cpp
@@ -49,6 +49,7 @@ TAO_Default_Resource_Factory::TAO_Default_Resource_Factory (void)
, options_processed_ (0)
, factory_disabled_ (0)
, cached_connection_lock_type_ (TAO_THREAD_LOCK)
+ , object_key_table_lock_type_ (TAO_THREAD_LOCK)
, corba_object_lock_type_ (TAO_THREAD_LOCK)
, flushing_strategy_type_ (TAO_LEADER_FOLLOWER_FLUSHING)
, codeset_manager_ (0)
@@ -373,6 +374,29 @@ TAO_Default_Resource_Factory::init (int argc, ACE_TCHAR *argv[])
}
}
else if (ACE_OS::strcasecmp (argv[curarg],
+ ACE_LIB_TEXT("-ORBObjectKeyTableLock")) == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ if (ACE_OS::strcasecmp (name,
+ ACE_LIB_TEXT("thread")) == 0)
+ this->object_key_table_lock_type_ = TAO_THREAD_LOCK;
+ else if (ACE_OS::strcasecmp (name,
+ ACE_LIB_TEXT("null")) == 0)
+ {
+ // @@ Bug 940 :This is a sort of hack now. We need to put
+ // this in a common place once we get the common
+ // switch that is documented in bug 940...
+ this->object_key_table_lock_type_ = TAO_NULL_LOCK;
+ }
+ else
+ this->report_option_value_error (ACE_LIB_TEXT("-ORBObjectKeyTableLock"), name);
+ }
+ }
+ else if (ACE_OS::strcasecmp (argv[curarg],
ACE_LIB_TEXT("-ORBCorbaObjectLock")) == 0)
{
curarg++;
@@ -874,6 +898,23 @@ TAO_Default_Resource_Factory::locked_transport_cache (void)
ACE_Lock *
+TAO_Default_Resource_Factory::create_object_key_table_lock (void)
+{
+ ACE_Lock *the_lock = 0;
+
+ if (this->object_key_table_lock_type_ == TAO_NULL_LOCK)
+ ACE_NEW_RETURN (the_lock,
+ ACE_Lock_Adapter<ACE_SYNCH_NULL_MUTEX>,
+ 0);
+ else
+ ACE_NEW_RETURN (the_lock,
+ ACE_Lock_Adapter<TAO_SYNCH_MUTEX>,
+ 0);
+
+ return the_lock;
+}
+
+ACE_Lock *
TAO_Default_Resource_Factory::create_corba_object_lock (void)
{
ACE_Lock *the_lock = 0;
diff --git a/TAO/tao/default_resource.h b/TAO/tao/default_resource.h
index 44c2811e2bd..a00ebe36700 100644
--- a/TAO/tao/default_resource.h
+++ b/TAO/tao/default_resource.h
@@ -126,6 +126,7 @@ public:
virtual int purge_percentage (void) const;
virtual int max_muxed_connections (void) const;
virtual ACE_Lock *create_cached_connection_lock (void);
+ virtual ACE_Lock *create_object_key_table_lock (void);
virtual ACE_Lock *create_corba_object_lock (void);
virtual int locked_transport_cache (void);
virtual TAO_Flushing_Strategy *create_flushing_strategy (void);
@@ -220,6 +221,9 @@ private:
Lock_Type cached_connection_lock_type_;
/// Type of lock used by the corba object.
+ Lock_Type object_key_table_lock_type_;
+
+ /// Type of lock used by the corba object.
Lock_Type corba_object_lock_type_;
enum Flushing_Strategy_Type