summaryrefslogtreecommitdiff
path: root/ACE/TAO/tao/MProfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/TAO/tao/MProfile.cpp')
-rw-r--r--ACE/TAO/tao/MProfile.cpp371
1 files changed, 371 insertions, 0 deletions
diff --git a/ACE/TAO/tao/MProfile.cpp b/ACE/TAO/tao/MProfile.cpp
new file mode 100644
index 00000000000..c4c763c7f6c
--- /dev/null
+++ b/ACE/TAO/tao/MProfile.cpp
@@ -0,0 +1,371 @@
+// -*- C++ -*-
+//
+// $Id$
+#include "tao/MProfile.h"
+#include "tao/Profile.h"
+#include "tao/PolicyC.h"
+#include "tao/ORB_Constants.h"
+#include "tao/SystemException.h"
+
+#include "ace/Log_Msg.h"
+#include "ace/Guard_T.h"
+#include "ace/CORBA_macros.h"
+
+ACE_RCSID (tao,
+ MProfile,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "tao/MProfile.inl"
+#endif /* __ACE_INLINE__ */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_MProfile::~TAO_MProfile (void)
+{
+ if (this->policy_list_ != 0)
+ {
+ CORBA::ULong const len = this->policy_list_->length ();
+ for (CORBA::ULong i = 0; i < len; ++i)
+ {
+ try
+ {
+ CORBA::Policy_ptr policy = (*this->policy_list_)[i];
+ policy->destroy ();
+ }
+ catch (const ::CORBA::Exception&)
+ {
+ // Ignore all exceptions to allow other policies to be
+ // destroyed.
+ }
+ }
+
+ delete this->policy_list_;
+ }
+
+ this->cleanup ();
+}
+
+void
+TAO_MProfile::cleanup (void)
+{
+ if (this->pfiles_ != 0)
+ {
+ for (TAO_PHandle i = 0; i < this->last_; ++i)
+ if (this->pfiles_[i])
+ this->pfiles_[i]->_decr_refcnt ();
+ delete [] this->pfiles_;
+ this->pfiles_ = 0;
+ }
+
+ this->current_ = 0;
+ this->size_ = 0;
+ this->last_ = 0;
+}
+
+int
+TAO_MProfile::set (CORBA::ULong sz)
+{
+ if (sz == 0)
+ {
+ this->cleanup ();
+ return 0;
+ }
+
+ // See if we already have an existing profile list or if we need to
+ // get ridof what we have.
+ if (this->size_ != 0)
+ {
+ // Release all of our profiles.
+
+ for (TAO_PHandle h = 0;
+ h < this->size_;
+ ++h)
+ if (this->pfiles_[h])
+ {
+ this->pfiles_[h]->_decr_refcnt ();
+ this->pfiles_[h] = 0;
+ }
+
+ // Next see if we can reuse our profile list memory
+ if (this->size_ < sz)
+ {
+ // we cant reuse memory since the current array is too small!
+ delete [] this->pfiles_;
+
+ ACE_NEW_RETURN (this->pfiles_,
+ TAO_Profile *[sz],
+ -1);
+ this->size_ = sz;
+ }
+ // else , leave this->size and this->pfiles alone!
+ }
+ else
+ {
+ // first time, initialize!
+ ACE_NEW_RETURN (this->pfiles_,
+ TAO_Profile *[sz],
+ -1);
+ this->size_ = sz;
+ }
+
+ this->last_ = 0;
+ this->current_ = 0;
+
+ for (TAO_PHandle i = 0; i != this->size_; ++i)
+ this->pfiles_[i] = 0;
+
+ return this->size_;
+}
+
+int
+TAO_MProfile::set (const TAO_MProfile &mprofile)
+{
+ // NOTE: We use mprofile->last_ instead of mprofile->size_ to set
+ // this->size_. This is so we can use set () to trim a profile
+ // list!!
+
+ this->set (mprofile.last_);
+
+ // set indexes ...
+ this->last_ = mprofile.last_;
+
+ // These are set in set (ULong);
+ // this->current_ = 0;
+ // this->forward_from_ = 0;
+
+ // Now reference all profiles.
+ for (TAO_PHandle h = 0; h < this->last_; ++h)
+ {
+ this->pfiles_[h] = mprofile.pfiles_[h];
+ if (this->pfiles_[h] != 0)
+ this->pfiles_[h]->_incr_refcnt ();
+ }
+
+ return 1;
+}
+
+// Not thread safe!
+int
+TAO_MProfile::grow (CORBA::ULong sz)
+{
+ if (sz <= this->size_)
+ return 0;
+
+ // get the additional space
+ TAO_Profile **new_pfiles = 0;
+ TAO_Profile **old_pfiles = 0;
+ ACE_NEW_RETURN (new_pfiles,
+ TAO_Profile *[sz],
+ -1);
+
+ old_pfiles = this->pfiles_;
+
+ // got it, now copy profiles
+ for (TAO_PHandle h = 0; h < this->size_; ++h)
+ {
+ new_pfiles[h] = old_pfiles[h];
+ old_pfiles[h] = 0;
+ }
+
+ this->pfiles_ = new_pfiles;
+ this->size_ = sz;
+ delete [] old_pfiles;
+
+ return 0;
+}
+
+int
+TAO_MProfile::add_profile (TAO_Profile *pfile)
+{
+ // skip by the used slots
+ if (last_ == size_) // full!
+ {
+ if (this->grow (this->size_ + 1) < 0)
+ return -1;
+ }
+
+ pfiles_[last_++] = pfile;
+
+ if (pfile && pfile->_incr_refcnt () == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Unable to increment reference ")
+ ACE_TEXT ("count in add_profile!\n")),
+ -1);
+
+ return last_ - 1;
+}
+
+int
+TAO_MProfile::add_profiles (TAO_MProfile *pfiles)
+{
+ // this->size_ == total number of profiles we can hold
+ // this->last_ == the index of the last profile
+ CORBA::ULong const space = this->size_ - this->last_;
+
+ if (space < pfiles->last_)
+ {
+ // we need to grow!
+ if (this->grow (this->last_ + pfiles->last_) < 0)
+ return -1;
+ }
+
+ // copy over profiles
+ for (TAO_PHandle h = 0; h < pfiles->last_; ++h)
+ {
+ if (this->add_profile (pfiles->pfiles_[h]) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+
+// the layout for a full list of 7 Profiles.
+//
+// last_ == one past the last valid entry, so if the list has 2
+// profiles then last_ equals 2.
+// current_ == index of the next profile to be returned (or one past
+// the last returned.
+//
+// this->size_ = 7; current_ = 3; last_ = 7
+// 0, 1, 2, 3, 4, 5, 6}
+// { _, _, _, _, ..., _}
+//
+int
+TAO_MProfile::remove_profile (const TAO_Profile *pfile)
+{
+ TAO_PHandle h;
+ int found = 0;
+ for (h = 0; h < this->last_; ++h)
+ {
+ if (this->pfiles_[h]->is_equivalent (pfile))
+ { // remove it!
+ TAO_Profile *old = this->pfiles_[h];
+ this->pfiles_[h] = 0;
+ old->_decr_refcnt ();
+ // shift other profiles up one
+ // note, if h == last_ - 1 then do nothing.
+ for (TAO_PHandle inner = h; inner < this->last_ - 1; ++inner)
+ {
+ this->pfiles_[inner] = this->pfiles_[inner + 1];
+ }
+ // subtract 1 from last_ to indicate we have one fewer profiles
+ this->last_--;
+ found = 1;
+ break;
+ }
+ }
+ if ( found == 0)
+ return -1; // profile not found.
+ return 0;
+}
+
+int
+TAO_MProfile::remove_profiles (const TAO_MProfile *pfiles)
+{
+ for (TAO_PHandle h = 0; h < pfiles->last_; ++h)
+ {
+ if (this->remove_profile (pfiles->pfiles_[h]) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+CORBA::Boolean
+TAO_MProfile::is_equivalent (const TAO_MProfile *rhs)
+{
+ // Two profile lists are equivalent iff at least one of the profiles
+ // from the first list is_equivalent to at least one of the profiles
+ // from the second list!!
+ for (TAO_PHandle h1 = 0; h1 < this->last_; ++h1)
+ for (TAO_PHandle h2 = 0; h2 < rhs->last_; ++h2)
+ if (this->pfiles_[h1]->is_equivalent (rhs->pfiles_[h2]))
+ return 1;
+
+ return 0;
+}
+
+CORBA::ULong
+TAO_MProfile::hash (CORBA::ULong max)
+{
+ CORBA::ULong hashval = 0;
+
+ if (this->last_ == 0)
+ return 0;
+
+ for (TAO_PHandle h = 0; h < this->last_ ; ++h)
+ {
+ hashval += pfiles_[h]->hash (max);
+ }
+
+ // The above hash function return an ULong between 0 and max here we
+ // simply take the average value and round.
+ //return hashval / this->last_;
+ // Changed to a mod value instead of an average.
+ return hashval % max;
+}
+
+void
+TAO_MProfile::create_policy_list (void)
+{
+ ACE_NEW_THROW_EX (this->policy_list_,
+ CORBA::PolicyList,
+ CORBA::NO_MEMORY (0,
+ CORBA::COMPLETED_NO)
+ );
+}
+
+void
+TAO_MProfile::init_policy_list (void)
+{
+ // The first time this method is called
+ // it causes the initialization of the policies
+ // for the current profile.
+
+ this->get_current_profile ()->get_policies (*this->policy_list_);
+
+ this->is_policy_list_initialized_ = true;
+}
+
+CORBA::PolicyList *
+TAO_MProfile::policy_list (void)
+{
+ if (!this->is_policy_list_initialized_)
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX,
+ guard,
+ this->mutex_,
+ 0);
+
+ if (this->policy_list_ == 0)
+ {
+ this->create_policy_list ();
+
+ this->init_policy_list ();
+ }
+ }
+ CORBA::PolicyList *ret_val = 0;
+ ACE_NEW_THROW_EX (ret_val,
+ CORBA::PolicyList (*this->policy_list_),
+ CORBA::NO_MEMORY (0,
+ CORBA::COMPLETED_NO));
+
+ return ret_val;
+}
+
+int
+TAO_MProfile::give_shared_profile (TAO_Profile *pfile)
+{
+ for (unsigned i = 0; i < this->last_; i++)
+ if (pfile->tag() == this->pfiles_[i]->tag() &&
+ pfile->compare_key(this->pfiles_[i]))
+ {
+ this->pfiles_[i]->add_generic_endpoint(pfile->endpoint());
+ pfile->_decr_refcnt();
+ return i;
+ }
+ return this->give_profile(pfile, 0);
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL